使用 lib 时无法解析符号...有什么想法吗?

发布于 2024-11-04 06:25:41 字数 389 浏览 0 评论 0原文

用C编写(写入C++项目):

我在VS08中有两个项目在同一解决方案下。一个是 DLL 文件,另一个(“运行程序”)是用于使用/测试 DLL 文件的控制台应用程序。头文件有一个包含所有函数的头文件(__declspec(dllexport))。当我通过运行器控制台应用程序使用不带任何参数的函数时,它们运行正常。当我尝试使用参数调用函数时,我无法解析符号...错误。奇怪的是,VS08 识别了该函数,我可以使用右键菜单从运行程序 main() 打开它,但它找不到它。

值得一提的是,我包含了头文件,而不是导入带有函数指针的 DLL...我的感觉是,函数在编译过程中以某种方式被重命名,并且链接器无法找到带有参数的函数。如果我能够看到新名称的列表(在目标文件内?)也许我可以将它们包含在头文件中来解决这个问题?

谢谢。

Written in C (into a C++ project):

I have two projects in VS08 under the same solution. One is a DLL file and the other ("runner") is the a console application for using/testing the DLL file. The header file has a header file with all the functions (__declspec(dllexport)). When I use functions without any arguments, by the runner console application, they run OK. When I try to call a function with arguments I get unable to resolve symbol... error. The strange thing is that VS08 recognizes the function and I can open it from the runner main() with the right-click menu, however it can't find it.

Worth mentioning that I am including the header file and not importing the DLL with function pointers... My feeling is that the functions get renamed somehow in the compiling process and the linker can't find the functions with the arguments. If I would be able to to see the list of new names (inside the object file?) maybe I could include them in the header file to fix this?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

御守 2024-11-11 06:25:41

用 C 编写(在 C++ 项目中):

这可能是一个非常好的线索。 C 程序不能使用用 C++ 编写的函数。当您使用 __declspec(dllexport) 时,该函数将以其 C++ 名称导出。这是由编译器修饰的,这是允许重载函数正确链接的技巧。 AC编译器不应用相同类型的装饰,链接器会抱怨它找不到该函数。

要实现此功能,您必须使用 extern "C" 声明符来声明该函数。使 .h 文件如下所示:

#ifdef __cplusplus
  extern "C" {
#endif

#undef DLLEXPORT
#ifdef BUILDING_MYDLL
#  define DLLEXPORT __declspec(dllexport)
#else
#  define DLLEXPORT __declspec(dllimport)
#endif

DLLEXPORT void Foo(int arg);
// etc..

#ifdef __cplusplus
  }
#endif

在 DLL 项目中,使用“项目 + 属性”、“C/C++”、“预处理器”,并将 BUILDING_MYDLL 添加到“预处理器定义”设置中。

对这个疯狂宏的简短解释:#ifdef __cplusplus 确保所有 DLL 声明在由 C++ 编译器编译时都声明为 extern "C",以便它们与 C 编译器符号匹配。 DLLEXPORT 宏确保在构建 DLL 时导出函数,在链接另一个项目中的 DLL 导入库时导入函数。

您可以通过在 DLL 上使用 /exports 选项运行 dumpbin.exe 实用程序来进行其他故障排除。它显示导出函数的确切名称。从 Visual Studio 命令提示符运行它。您在输出中看到的名称与链接器错误消息之间的不匹配是出现问题的明确标志。

Written in C (into a C++ project):

That's possibly a pretty good lead. A C program cannot consume functions that were written in C++. When you use __declspec(dllexport), the function gets exported with its C++ name. Which is decorated by the compiler, a trick to allow overloaded functions to link properly. A C compiler doesn't apply the same kind of decoration, the linker will complain that it can't find the function.

To make this work, you have to declare the function with the extern "C" declarator. Make the .h file look like this:

#ifdef __cplusplus
  extern "C" {
#endif

#undef DLLEXPORT
#ifdef BUILDING_MYDLL
#  define DLLEXPORT __declspec(dllexport)
#else
#  define DLLEXPORT __declspec(dllimport)
#endif

DLLEXPORT void Foo(int arg);
// etc..

#ifdef __cplusplus
  }
#endif

In your DLL project, use Project + Properties, C/C++, Preprocessor and add BUILDING_MYDLL to the Preprocessor Definitions settings.

A short explanation for this macro madness: the #ifdef __cplusplus ensures that all the DLL declarations are declared extern "C" when they are compiled by the C++ compiler so that they'll match the C compiler symbols. The DLLEXPORT macro ensures that the functions are exported when you build the DLL, imported when you link the DLL import library in another project.

You can get additional troubleshooting from the dumpbin.exe utility by running it with the /exports option on your DLL. It shows the exact names of exported functions. Run it from the Visual Studio command prompt. A mismatch between the names you see in the output verses the linker error messages is a sure sign of trouble.

陌伤浅笑 2024-11-11 06:25:41

首先:智能感知找到它('打开右键菜单' eeeeck?)并不能证明;它证明您将声明放入头文件中;

您对名称修饰的看法可能是正确的:如果您有 C 外部文件,则需要在 extern "C" {} 块内声明它们:

extern "C" {

    void dostuff(int param1, char* param2);

}

而不是

extern void dostuff(int param1, char* param2);

最灵活的方法可能是包含 extern " C" 有条件地围绕完整的 C 头文件:

// Sample.h
#if defined(__cplusplus)
extern "C"
{
#endif

// Function declarations

#if defined(__cplusplus)
}
#endif 

请参阅 MSDN 了解更多信息

First off: Intellisense finding it ('open for the rightclick menu' eeeeck?) is no proof; it proves you put the declaration in a header file;

You are probably right about the name mangling thing: If you have C externals you need to declare them inside an extern "C" {} block:

extern "C" {

    void dostuff(int param1, char* param2);

}

instead of

extern void dostuff(int param1, char* param2);

The most flexible approach is probably to include the extern "C" around the complete C header file conditionally:

// Sample.h
#if defined(__cplusplus)
extern "C"
{
#endif

// Function declarations

#if defined(__cplusplus)
}
#endif 

See MSDN for more info

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文