我正在为一个软件编写一个插件DLL,DLL编译得很好,但软件无法访问DLL的功能。我知道该软件可以识别DLL。
当我在Dependency Walker中检查DLL时,函数名称附加了@x
,例如Foo@4
这意味着Foo有1个参数(函数参数的数量乘以4)。
然而,当我检查一个已知可以工作DLL函数的插件DLL时,最后没有附加@x
。由于这个DLL已知可行,而我的DLL无效,我认为这与它有关。
有效的DLL在其导出的函数上使用__declspec(dllexport) __stdcall
。请注意,我只有好DLL的源代码。我知道它有效,因为我有自己的DLL文件,我自己没有编译。据我所知,这是在Borland IDE中编译的,所以它可能是Eclipse特有的问题吗?
有谁知道可能出错的地方和/或我如何使DLL正常工作?
编辑我应该指出我正在使用Eclipse IDE,使用MINGW编译器。
答案 0 :(得分:4)
Dependency Walker显示的名称是真实姓名。它们是装饰名称,@<num>
的存在表示使用__stdcall
导出的__declspec(dllexport)
函数。
如果您在加载时使用随附的导入库(.lib文件)链接到DLL,则真实名称和修饰名称之间的映射将包含在该导入库中。如果您在运行时与GetProcAddress
链接,则需要使用装饰名称。
由于您正在编写插件,因此主机将使用运行时链接。您必须遵守其特定的命名约定。这意味着你需要压制名称装饰。对于__stdcall
函数,这意味着您必须使用.def文件而不是__declspec(dllexport)
导出函数。
当然,在编写插件时,你的调用约定是错误的,这似乎是合理的。也许主持人期待cdecl
。我不知道你应该使用哪种调用约定。主机应用程序的文档可能会指定调用约定。
答案 1 :(得分:2)
@x
语法意味着调用者必须清理堆栈的x
个字节。那是因为您使用了_stdcall
调用约定。现有代码假定_cdecl
函数,不会清理堆栈,因此不能使用DLL。