How to use delay loading with a DLL that exports C

2019-01-23 17:55发布

I have a DLL one.dll that uses a class TwoClass exported from two.dll via class __declspec(dllexport). I'd like one.dll to use /delayload for two.dll, but I get a link error:

LINK : fatal error LNK1194: cannot delay-load 'two.dll' due to import
of data symbol '"__declspec(dllimport) const TwoClass::`vftable'"
(__imp_??_7TwoClass@@6B@)'; link without /DELAYLOAD:two.dll

That's in a Release build; in a Debug build it works. (I don't know what the difference is between Release and Debug in terms of vtable exports, nor can I find any compiler switches or pragmas to control it.)

How can I use /delayload with a DLL that exports classes like this in a Release build?

4条回答
祖国的老花朵
2楼-- · 2019-01-23 18:15

Check if one.dll contains a source file that includes TwoClass.hxx but does not actually use it. In addition check whether TwoClass meets the conditions for compiler generated methods (see conditions for automatic generation).

In my case I actually didn't need a compiler generated copy ctor nor the assignment operator for TwoClass so I declared them in the private: section without providing a definition. That created build errors for one.dll, which guided me to the source files that unnecessarily included TwoClass.hxx. After removing the unnecessary includes I was able to compile and link with optimization turned on and with /delayload.

I assume that the unnecessary #include statements misguided the optimizer to copy the compiler generated methods for TwoClass into the .obj files to be linked into one.dll even though they were not used in these .obj files. These unnecessary compiler generated methods for TwoClass seem to prevent a link with /delayload.

查看更多
劫难
3楼-- · 2019-01-23 18:17

I had exactly same problem with class which contained inline implementation for exported class.

class __declspec(dllimport) VidExpInternal : public VidExpBase
{
public:
    VidExpInternal(TCHAR* msg=_T(""), int ln=__LINE__, TCHAR* filechar=_T(__FILE__)) :
        VidExpBase (msg,ln,filechar) {}

I've moved inline implementation to .cpp file - after that everything worked out smoothly.

class __declspec(dllimport) VidExpInternal : public VidExpBase
{
public:
    VidExpInternal(TCHAR* msg=_T(""), int ln=__LINE__, TCHAR* filechar=_T(__FILE__));
查看更多
SAY GOODBYE
4楼-- · 2019-01-23 18:19

Define a factory function that hands out instances of a class, much like in COM. This also requires that the interface(s) of the classes be public, but that's a given as well when someone imports a class.

查看更多
仙女界的扛把子
5楼-- · 2019-01-23 18:28

Have a look here, seems that the person had exactly the same problem and found a workaround

I managed to get the delay loading to work in release build by disabling the optimizations on the translation unit that was using SomeClass class - somehow it took away the dependency on exported vtable.

查看更多
登录 后发表回答