使用托管组件链接到静态库
在为我的个人小应用程序创建 GUI 后,我尝试将其编译为静态库以在另一个项目中使用。 GUI 已创建,并通过托管公共引用类执行其他任务,该类当前只有 5 个函数,但将添加到其中。
这是我在静态库中的头文件,它将包含在另一个项目中(好吧,至少是一个只有公共函数的新头文件,所有额外的东西都将被删除);
#ifndef GUIInterface_H #define GUIInterface_H #include #include "MainForm.h" using namespace System; using namespace System::Threading; public ref class GUIInterface { private: ThreadStart^ GUIThreadDelegate; Thread^ GUIThread; void GUIThreadFunction() { ANNGUI::Application::EnableVisualStyles(); ANNGUI::Application::Run(gcnew ANNGUI::MainForm()); return; } public: int CreateGUI(); int DestroyGUI(); int GetInputData(); bool CheckNewInput(); int NetworkState(); }; #endif
这是从其他项目 (.exe) 访问它的方式
#include "main.h" int main() { GUIInterface ^GUI = gcnew(GUIInterface); GUI->CreateGUI(); return 0; }
main.h 仅包含类定义,如上面所示的头文件,减去私有内容。
我正在使用 Visual Studio 2010 Express C++。这两个项目都是使用 /clr 开关编译的。静态库被设置为 .exe 项目中的引用。当我将静态库编译为 DLL 时,程序运行完美(在我删除应用程序中的 main.h 之后)。当它被编译为静态库时,用于与 GUI 通信的每个函数都会出现 LNK2020 错误。
我将 .exe 与 /VERBOSE 选项链接起来以查看输出。链接器多次精确地查找 .lib 所在的位置,但从未说过它找到了它,即使它正在精确地查找正确的路径和正确的文件。另外,如果这意味着什么,我的 .lib 构建得很好,但将此作为警告。
.NETFramework,Version=v4.0.AssemblyAttributes.obj : warning LNK4221: This object file does not define any previously undefined public symbols, so it will not be used by any link operation that consumes this library
我的问题是,为什么链接器在正确的位置寻找 .lib,却没有在它的面前看到它?我该如何解决这个问题以便我可以使用我的静态.lib?
After creating a GUI for my personal little application, I am trying to compile it as a static library to use in another project. The GUI is created and has other tasks performed with it through a managed public ref class that currently only has 5 functions, but will be added to.
This is my header file in the static library that would be included in the other project (well, at least a new one with only the public functions, all the extra stuff would be removed);
#ifndef GUIInterface_H #define GUIInterface_H #include #include "MainForm.h" using namespace System; using namespace System::Threading; public ref class GUIInterface { private: ThreadStart^ GUIThreadDelegate; Thread^ GUIThread; void GUIThreadFunction() { ANNGUI::Application::EnableVisualStyles(); ANNGUI::Application::Run(gcnew ANNGUI::MainForm()); return; } public: int CreateGUI(); int DestroyGUI(); int GetInputData(); bool CheckNewInput(); int NetworkState(); }; #endif
This is how it would be accessed from the other project (.exe)
#include "main.h" int main() { GUIInterface ^GUI = gcnew(GUIInterface); GUI->CreateGUI(); return 0; }
The main.h just contains the class definitions like the header file shown above, minus the private stuff.
I am using Visual Studio 2010 Express C++. Both projects are compiled with /clr switch. The static library is set as a reference in the .exe project. When I compile the static library as a DLL instead, the program runs perfectly (after I remove the main.h in the application). When it is compiled as a static library I get a LNK2020 Error for each of the functions used to communicate with the GUI.
I linked the .exe with the /VERBOSE option to see the output. The linker looks exactly where the .lib is multiple times, but never says it found it even though it's looking EXACTLY in the right path and for the right file. Also, if it means anything, my .lib builds fine but gets this as a warning.
.NETFramework,Version=v4.0.AssemblyAttributes.obj : warning LNK4221: This object file does not define any previously undefined public symbols, so it will not be used by any link operation that consumes this library
My question is, why is the linker looking in the right place for the .lib, but not seeing it right in front of it's face? How can I go about fixing this so that I can use my static .lib?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
静态 .lib 不是托管代码的有效目标选项。没有实现的机制可以使与托管类型关联的最重要的元数据得到与代码相同的处理。它不能被分割成碎片并再次粘合在一起。 MSFT 团队可能考虑过这一点,但被 .obj 文件格式所需的巨大更改吓跑了。这是一个猜测。如果有一个好的错误消息就好了。这是事实。
您必须选择一个 DLL 作为目标。在运行时,JIT编译器执行与链接器相同的功能,它只从客户端实际使用的DLL程序集中提取代码。
A static .lib is not a valid target option for managed code. There is no implemented mechanism to get the all-important metadata associated with managed types the same kind of treatment as code. It cannot be carved up in bits in pieces and glued together again. The MSFT team probably considered it but got scared away by the massive changes required to the .obj file format. That's a guess. A good error message would have been nice. That's a fact.
You must select a DLL as the target. At runtime, the JIT compiler performs the same function as the linker, it only pulls code from the DLL assembly that is actually used by the client.