我坚持修复传统的Visual C ++ 6应用程序。在C ++ DLL源代码中我放了
extern "C" _declspec(dllexport) char* MyNewVariable = 0;
导致MyNewVariable在导出表中显示(很好地未修饰)(如dumpbin / exports blah.dll所示)。但是,我无法弄清楚如何声明变量,以便我可以在C源文件中访问它。我尝试过各种各样的事情,包括
_declspec(dllimport) char* MyNewVariable;
但这只是给我一个链接器错误:
未解析的外部符号“__declspec(dllimport)char * MyNewVariable”(__ imp_?MyNewVariable @@ 3PADA)
extern "C" _declspec(dllimport) char* MyNewVariable;
正如托尼(以及我之前尝试过的)所建议的那样导致了不同的预期装饰,但仍然没有将其删除:
未解析的外部符号__imp__MyNewVariable
如何编写声明,以便可以从C app访问C ++ DLL变量?
由botismarius和其他人确认(非常感谢所有),我需要链接DLL的.lib。为了防止名称被破坏,我需要声明它(在C源代码中)没有装饰器,这意味着我需要使用.lib文件。
答案 0 :(得分:5)
你必须链接编译DLL后生成的lib。在项目的链接器选项中,必须添加.lib
文件。是的,您还应该将变量声明为:
extern "C" { declspec(dllimport) char MyNewVariable; }
答案 1 :(得分:4)
extern“C”是你如何删除装饰 - 它应该可以使用:
extern“C”declspec(dllimport)char MyNewVariable;
或者如果你想要一个可以被C ++或C(带/ TC开关)使用的标题
#ifdef __cplusplus
extern "C" {
#endif
declspec(dllimport) char MyNewVariable;
#ifdef __cplusplus
}
#endif
当然,链接到执行导出的dll生成的导入库。
答案 2 :(得分:2)
我不确定是谁修改了botismarius,因为他是对的。原因是生成的.lib是导入库,可以很容易地用__declspec(dllimport)
简单地声明外部变量/函数,并且只需使用它。导入库只是自动执行必要的LoadLibrary()
和GetProcAddress()
调用。没有它,您需要手动调用它们。
答案 3 :(得分:1)
他们都是对的。错误消息描述__imp_?MyNewVariable@@3PADA
的事实意味着它正在寻找装饰名称,因此外部“C”是必需的。但是,与导入库的链接也是必要的,否则您将获得不同的链接错误。
答案 4 :(得分:1)
@Graeme:你也是对的。我认为OP使用的“C”编译器不是强制执行C99标准,而是编译为C ++,因此会破坏名称。真正的C编译器无法理解extern "C"
关键字的“C”部分。
答案 5 :(得分:1)
在 dll源代码中,您应该使用此实现,以便.lib文件导出符号:
extern "C" _declspec(dllexport) char* MyNewVariable = 0;
c客户端应在此声明中使用标头,以便客户端代码导入符号:
extern "C" _declspec(dllimport) char* MyNewVariable;
如果dll源代码中包含#include-ed,则此标头将导致编译错误,因此通常将其放在导出标头中,该标头仅用于导出的功能,且仅由客户端使用。
如果需要,您还可以创建一个“通用”标题,可以包含在以下任何位置:
#ifdef __cplusplus
extern "C" {
#endif
#ifdef dll_source_file
#define EXPORTED declspec(dllexport)
#else
#define EXPORTED declspec(dllimport)
#endif dll_source_file
#ifdef __cplusplus
}
#endif
EXPORTED char* MyNewVariable;
然后dll源代码如下所示:
#define dll_source_code
#include "universal_header.h"
EXPORTED char* MyNewVariable = 0;
客户端看起来像这样:
#include "universal_header.h"
...
MyNewVariable = "Hello, world";
如果你这么做了,顶部的怪物#ifdef可以进入export_magic.h并且universal_header.h变为:
#include "export_magic.h"
EXPORTED char *MyNewVariable;
答案 6 :(得分:0)
我在Windows中编程时从未使用过__declspec(dllimport)。你应该能够简单地声明
extern "C" char* MyNewVariable;
并链接到编译DLL时创建的.lab。