能力值:
( LV2,RANK:10 )
2 楼
看起来像是你把GetModuleHandleA当成c调用了
能力值:
( LV2,RANK:10 )
3 楼
正常的__stdcall找不到符号应该是GetModuleHandleA@0
能力值:
( LV2,RANK:10 )
4 楼
extern "C"
能力值:
( LV7,RANK:100 )
5 楼
这个好像是C++程序里才行,我用的是Flexm SDK,是C程序的
能力值:
( LV7,RANK:100 )
6 楼
论坛的朋友给的解答,其余的问题未给答复。
kernel32.lib does not export GetModuleHandleA, but _imp__GetModuleHandleA
So need to replace Code:
externdef GetModuleHandleA:dword
with Code:
pr1 typedef PROTO :DWORD
externdef _imp__GetModuleHandleA@4:PTR pr1
GetModuleHandleA equ <_imp__GetModuleHandleA@4>
我想知道<1> 怎么知道_imp__GetModuleHandleA <2>pr1是关键字吗,用pr2呢?<3>_imp__GetModuleHandleA@4,这里4是什么意思,参数个数?
我还有几十个类似的错,该怎么改呢?
_GetLastError
_MultiByteToWideChar
_WideCharToMultiByte
_GetCurrentProcess
_VirtualAlloc
_VirtualFree
_SetLastError
_WriteFile
_GetModuleFileNameA
_GetSystemInfo
_VirtualProtect
_GetCPInfo
_GetLocaleInfoA
_VirtualQuery
_InterlockedExchange
_InitializeCriticalSection
_GetStringTypeW
_GetStringTypeA
_LoadLibraryA
_GetProcAddress
_GetStdHandle
_GetCurrentThreadId
_LCMapStringW
_LCMapStringA
_ExitProcess
_TerminateProcess
_HeapReAlloc
_HeapAlloc
_HeapFree
能力值:
( LV7,RANK:100 )
7 楼
这段ASM代码是从IDA中dump出来的,我想产生obj文件,拿去和C程序LINK在一起用,结果就报了一堆无法解析的外部符号的错误。
能力值:
( LV2,RANK:10 )
8 楼
vs2008 连接是没问题的
能力值:
( LV4,RANK:50 )
9 楼
你下面的定义确实有问题
externdef __imp__GetModuleHandle@4:DWORD 这样才对
用masm的inc文件就没问题啦
能力值:
( LV2,RANK:10 )
10 楼
你的asm文件中都没有加入头文件和库文件的声明,当然报错。你看看罗云彬的《windows环境下32位汇编语言》中的asm的格式吧!
能力值:
( LV2,RANK:10 )
11 楼
4是指一个参数 8是两个参数
包含inc文件就行了
能力值:
( LV7,RANK:100 )
12 楼
加了也还是报这个错,是我加得不对吗?能否改一个给我参考下呢?谢谢啦:)
能力值:
( LV7,RANK:100 )
13 楼
瀚海兄,怎么用呢,我在asm文件里加了,可是VC LINK的时候还是报错啊?
.686p
.mmx
.xmm
.k3d
.model flat, C
option casemap: none
;Include定义
include user32.inc
includelib user32.lib
includelib ntdll.lib
include kernel32.inc
includelib kernel32.lib
include comdlg32.inc
includelib comdlg32.lib
能力值:
( LV7,RANK:100 )
14 楼
是不是就是number = 参数个数乘以4?
能力值:
( LV4,RANK:50 )
15 楼
在这之前还还要修改默认调用方式为stdcall方式 .model flat, C 修改成 .model flat,stdcall。
在inc文件里面并没有写调用方式是C还是stdcall
能力值:
( LV7,RANK:100 )
16 楼
这个我之前我还真不了解,急着获得答案继续往前,没去了解基础知识:)
明天试下,多谢瀚海兄指点:)
能力值:
( LV7,RANK:100 )
17 楼
瀚海兄, 我参照你的建议修改如下
.686
.model flat, stdcall, C ; => 不加"C", LINK编译时会报函数找不到
option casemap :none ;case sensitive
;include windows.inc
include kernel32.inc
includelib kernel32.lib
这样编译是通过了, 可是LINK时还是报同样的错, 能再帮我看一下不? 多谢啦!
error LNK2019: 无法解析的外部符号 _GetModuleHandleA,该符号在函数 ____crtInitCritSecAndSpinCount 中被引用
能力值:
( LV4,RANK:50 )
18 楼
我还是把这些语法解释下吧
.model 后面的C\stdcall等是不同的调用方式,编译的时候名字修改成不同的方式,C是直接在名字前加个下划线,stdcall是下划线后面再加@参数个数
option casemap :none 是告诉编译器,里面的函数名区分大小写。
根据你说的错误信息,应该是修改成 .model flat,stdcall ,不过其他函数在C里面调用定义前面都必须加上__stdcall或者WINAPI又或者是CALLBACK\APIENTRY\APIPRIVATE。
你先自己写一个小模块试试怎么用么。
; asm.asm
.386
.model stdcall,flat
option casemap:none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
.code
TestFunctionAdd proc ,v1:DWORD, v2:DWORD
mov eax,v1
add eax,v2
ret
TestFunctionAdd endp
GetExeModule proc
invoke GetModuleHandle,NULL
ret
GetExeModule endp
end
; 编译选项 ml /c /coff /Cp asm.asm
// callasm.Cpp文件
#include <windows.h>
#include <stdio.h>
#define CALLSTATIC WINAPI
#ifdef __cplusplus
extern "C" {
#endif
DWORD CALLSTATIC TestFunctionAdd(DWORD, DWORD);
HANDLE CALLSTATIC GetExeModule(VOID);
#ifdef __cplusplus
};
#endif
int main()
{
printf("3+5 = %d\n", TestFunctionAdd(3,5));
printf("Module Address: 0x%08X\n", GetExeModule());
return 0;
}
// 编译选项 cl callasm.cpp asm.obj ////************************************************************//////
////************************************************************//////
////************************************************************//////
如果model 后面一定要跟C,则在定义API的时候必须加stdcall
// asm.asm
.386
.model C,flat
option casemap:none
GetModuleHandleA proto stdcall ,:DWORD
.code
TestFunctionAdd proc ,v1:DWORD, v2:DWORD
mov eax,v1
add eax,v2
ret
TestFunctionAdd endp
GetExeModule proc
invoke GetModuleHandleA,0
ret
GetExeModule endp
end
; 编译选项 ml /c /coff /Cp asm.asm // callasm.cpp
// 相应的调用方式变成C的调用方式。
#include <windows.h>
#include <stdio.h>
#define CALLSTATIC __cdecl
#ifdef __cplusplus
extern "C" {
#endif
DWORD CALLSTATIC TestFunctionAdd(DWORD, DWORD);
HANDLE CALLSTATIC GetExeModule(VOID);
#ifdef __cplusplus
};
#endif
int main()
{
printf("3+5 = %d\n", TestFunctionAdd(3,5));
printf("Module Address: 0x%08X\n", GetExeModule());
return 0;
}
// 编译选项 cl callasm.cpp asm.obj
能力值:
( LV7,RANK:100 )
19 楼
瀚海兄,参照你的例子,我做了一个test case,能否帮忙看下LINK时报的错,为什么newtolower函数还是找不到呢?是不是newtest.c里定义的不对?谢谢啦!
LINK newtest.obj newtolower.obj /out:newtest.exe
Microsoft (R) Incremental Linker Version 9.00.21022.08
Copyright (C) Microsoft Corporation. All rights reserved.
newtest.obj : error LNK2019:
无法解析的外部符号 _newtolower@4 ,该符号在函数 _main 中被引用
newtest.exe : fatal error LNK1120: 1 个无法解析的外部命令
上传的附件:
能力值:
( LV4,RANK:50 )
20 楼
你申明的 newtolower 没有参数的牙,。你要传递一个参数后面要跟的
newtolower proc near ,argv1:DWORD
能力值:
( LV7,RANK:100 )
21 楼
的确过了,不过产生的newtest.exe在运行的时候出错(如附图),之前用下面的方法,exe文件产生了,不过也有同样的运行错误。
pr1 typedef PROTO :DWORD
externdef _imp__GetModuleHandleA@4:PTR pr1
GetModuleHandleA equ <_imp__GetModuleHandleA@4>
这段代码是从IDA中dump出来修改而来的,看来dump的时候最好还是不要dump库函数,实在是难弄
之前只想弄个结果出来,中间的很多基础知识都暂时忽略了,还得好好学习啊。
我先结贴,兄如果有空就再帮我看看这个运行的错误,多谢瀚海兄的耐心指导:)
上传的附件: