简体   繁体   English

为什么我不能使用 GetProcAddress 在 DLL 中调用 C++ static class 工厂方法?

[英]Why can't I call a C++ static class factory method in a DLL with GetProcAddress?

I'm trying to load a hypothetical plugin with the following header:我正在尝试使用以下 header 加载一个假设的插件:

#ifndef _DLL_H_
#define _DLL_H_

#if BUILDING_DLL
# define DLLIMPORT __declspec (dllexport)
#else /* Not BUILDING_DLL */
# define DLLIMPORT __declspec (dllimport)
#endif /* Not BUILDING_DLL */


class DLLIMPORT DllClass
{ 

  public:

    virtual ~DllClass(void);
    static DllClass* getPCFilter(); 
    virtual int Process(int a, int b);

  protected:

    DllClass();
};


#endif /* _DLL_H_ */

And my host code does:我的主机代码是这样的:

HINSTANCE hinstDLL;
hinstDLL = LoadLibrary(L"PCFilter.dll");

if(hinstDLL)
{
    typedef DllClass*(*Factory)();
    Factory fun1;

  fun1 = (Factory)GetProcAddress(hinstDLL, "DllClass::getPCFilter");

The dll opens but the GetProcAddress is not finding the static factory method. dll 打开,但 GetProcAddress 未找到 static 工厂方法。 Am I not supposed to be able to do it this way?我不应该这样做吗?

I've tried getting rid of the static method and instead, after the class declaration, doing the following:我尝试摆脱 static 方法,而是在 class 声明之后执行以下操作:

extern "C" DLLIMPORT void* getPCFilterInstance()
{
    return (void*)new DllClass();
}

But then, when compiling the host source, the linker complains:但是,在编译主机源时,linker 抱怨:

In function `getPCFilterInstance'::
[Linker Error] undefined reference to `_imp___ZN8DllClassC1Ev'

This I can solve by linking to the.a lib.我可以通过链接到.a 库来解决这个问题。 But isn't the idea of the DLL to not need to link at compile time?但是 DLL 的想法不是不需要在编译时链接吗?

You ignore the fact that the function name will be decorated ("name mangling") or not at all visible in the DLL interface (under the given name).您忽略了 function 名称将被修饰(“名称修改”)或在 DLL 界面(在给定名称下)中根本不可见的事实。 To my knowledge GetProcAddress doesn't do any name demangling, the linker however does (when statically importing a DLL with exported classes).据我所知, GetProcAddress不会进行任何名称修改,但是 linker 会进行(当静态导入带有导出类的 DLL 时)。

Best practice is to my knowledge to supply a factory function that has an undecorated name and a predefined calling convention much as COM prescribes it (see DllGetClassObject ).据我所知,最佳做法是提供一个工厂 function,它有一个未修饰的名称和一个预定义的调用约定,就像 COM 规定的那样(参见DllGetClassObject )。

Note: I should add that depending on the compiler/linker used, the decorated ("mangled") names will vary.注意:我应该补充一点,根据所使用的编译器/链接器,修饰的(“损坏的”)名称会有所不同。 Different compilers, different rules.不同的编译器,不同的规则。 Therefore they may not even be compatible amongst each other without considerable tinkering.因此,如果不进行大量修补,它们甚至可能彼此不兼容。

Edit: concerning the question:编辑:关于问题:

But isn't the idea of the DLL to not need to link at compile time?但是 DLL 的想法不是不需要在编译时链接吗?

Well, yes and no.好吧,是的,不是。 On Windows the whole process is somewhat different from the process in unixoid systems.在Windows上整个过程和unixoid系统中的过程有些不同。 The loader will take care of resolving dependencies and so on, but the point is that there are two ways of loading a DLL. One is by statically importing a DLL in which case the name resolution is done before your program gets to run (or fails before that) and the other is to load the DLL dynamically by means of LoadLibrary and friends and then resolve the function address with GetProcAddress .加载程序将负责解决依赖关系等问题,但重点是有两种加载 DLL 的方法。一种是静态导入 DLL,在这种情况下,名称解析在程序运行(或失败)之前完成之前),另一种是通过LoadLibrary和朋友动态加载 DLL,然后使用GetProcAddress解析 function 地址。 The latter has one variation (supported by the linker) called delay-loading.后者有一种变体(由链接器支持)称为延迟加载。 Ultimately it is still just the second method.归根结底还是只是第二种方法。

It is possible that delay-loading offers exactly what you want, by having the linker care about the names to resolve and still being able to handle failure of loading the DLL or resolving a name at runtime.通过让 linker 关心要解析的名称并且仍然能够处理加载 DLL 或在运行时解析名称的失败,延迟加载可能会提供您想要的。

You can use extern "C" statement to export your function with the same name as you've declared it in the code - otherwise it will get mangled by the c++ compiler您可以使用extern "C"语句导出 function 并使用与您在代码中声明的名称相同的名称 - 否则它将被 c++ 编译器破坏

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C ++ GetProcAddress()找不到静态类的方法 - C++ GetProcAddress() can't find the method of a static class 为什么我不能从C ++中的派生类实例调用模板化方法? - Why can't I call a templated method from a derived class instance in C++? 为什么我不能在未链接的DLL上调用方法,但可以做到这一点? C ++ - Why can't I call methods on unlinked DLL but can do this ? C++ 派生类中的静态方法可以在C ++中调用受保护的构造函数吗? - Can a static method in a derived class call a protected constructor in C++? 如何在C ++中宏#define静态方法调用? - How can I macro #define a static method call in C++? c++:为什么我不能为类“内部”的非常量静态成员赋值? - c++ : why I can't assign a value to a non-const static member "inside" a class? 为什么dll无法在C ++中使用? - Why dll can't be used in c++? 我可以在 C++ 中的对象声明上自动调用类的方法吗? - Can I automatically call a method of a class on object declaration in C++? 不能在c ++类实现文件(.cpp)中的静态方法上使用“static”关键字 - Can't use “static” keyword on a static method in a c++ class implementation file (.cpp) 静态工厂方法的C ++类型推导 - C++ type deduction for static factory method
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM