在 C++ 中调用静态链接的静态方法

Calling a statically-linked static method in C++

我正在尝试调用 C++ 的静态链接静态方法 class,但我收到 VS 链接器错误 LNK2019,"unresolved external symbol"。这是图书馆的来源:

// in header file
#define DllExport __declspec (dllexport)
class MyClass{
public:
    DllExport
    static HWND WINAPI myFunc();
};
// in cpp file
DllExport
HWND WINAPI MyClass::myFunc(){ /* create a GUI window that has instance of MyClass set as its property (using ::SetProp) */ }

myFunc 是作为创建 MyClass 对象的入口点,它隐藏在库中。只有这样的静态函数才能用于影响 MyClass 实例的功能(通过提供相应的 HWND)。 这是图书馆消费者:

#define DllImport __declspec(dllimport)
DllImport
HWND WINAPI myFunc();
...
int main(){
    HWND hWnd=myFunc();
    ... // work with the window and attached MyClass instance
}

(我相信)所有文件链接都设置正确 - 最初,myFunc 被设计为一个独立的函数,并且一切正常。我怀疑一定是某些调用对流不匹配导致链接器在 myFunc 上产生错误。 通读关于该主题的多篇文章,即

http://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-from-a-DLL

https://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx

但他们没有解决我的问题。

感谢您的建议!

您的导入头文件应该更像:

#define DllApi __declspec (dllexport)
class MyClass{
public:
    DllApi
    static HWND WINAPI myFunc();
};

由于您的目标是创建静态库,我们要做的第一件事就是消除对 dllexport/dllimport 的任何提及。此类说明符仅在您实际创建 DLL 项目时使用。

所以对于 lib.h,我们只需要这个(为了更好的措施添加了一些包含守卫):

// lib.h
#ifndef LIB_H
#define LIB_H

class MyClass{
public:
    static void myFunc();
};

#endif

WINAPI 规范也是不必要的,因为您是调用该方法的人并且可以使用默认调用约定而不会出现 ABI 问题(尽管如果您确实想使用 WINAPI,那么你需要在头文件中包含 <windows.h>

对于lib.cpp,我们只需要这个:

// lib.cpp
#include <Windows.h>
#include "lib.h"

void MyClass::myFunc(){
    ::MessageBox(0,"myFunc call!",NULL,0);
}

对于您的 app 项目中的 main.cpp,我们只需要:

// main.cpp
#include <iostream>
#include <D:\staticlink\lib\lib.h>

int main(){
    std::cout << "ahoj";
    MyClass::myFunc();
    char buf[10];
    std::cin >> buf;
    return 0;
}

我建议配置包含路径以通过项目设置查找 lib.h 而不是在源代码中使用绝对路径,但也许您可以在一切正常后稍后再这样做。

在那之后,如果问题仍然存在,您唯一需要确保的是您的 app 项目正确链接到 lib.lib(链接器设置)。