Vtable充满零

时间:2017-08-23 11:02:29

标签: c++ visual-studio clr vtable

我正在尝试将C ++代码编译为托管dll。我能够使用这个编译器和链接器选项编译它:

编译器:

/TP /analyze- /W3 /Zc:wchar_t /Zi /Od /sdl- /Fd"Debug\vc140.pdb" /Zc:inline /fp:precise /D "_SCL_SECURE_NO_WARNINGS" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_WINDLL" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /Oy- /clr:pure /FU"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll" /MDd /Fa"Debug\" /nologo /Zl /Fo"Debug\" /Fp"Debug\aaa.pch"

链接:

/OUT:"C:\Out\x86\Debug\aaa.dll" /MANIFEST /NXCOMPAT /PDB:"C:\aaa.pdb" /DYNAMICBASE "ucrtd.lib" "vcruntimed.lib" "libvcruntimed.lib" "msvcurtd.lib" "msvcrtd.lib" "libcmtd.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /FIXED:NO /DEBUG /DLL /CLRIMAGETYPE:PURE /INCREMENTAL:NO /PGD:"C:\Out\x86\Debug\aaa.pgd" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"Debug\aaa.dll.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /ASSEMBLYDEBUG /TLBID:1

我遇到的问题真的很奇怪。我有一个纯粹的抽象基类和该dll中的派生类。当我使用new创建该派生类的实例时,我可以看到它的vtable被零填充。

所以我无法调用任何虚函数。

我无法使用虚拟控制台应用程序重新创建此问题,因此我不知道,这可能是什么原因。据我从虚拟应用程序看到,没有调用crt或一些模糊的库来填充具有正确地址的vtable,只有几条装配线。

更新

代码中的问题如下所示:

class Connector : public IConnector
{
   public:
       Connector() : m_a(0), m_b(0)
       {}
   <...>
};

<...>

Connector * pc = new Connector();
Connector c;

IConnector有默认的ctor且没有字段,因此它什么也没做。

在监视窗口中,我可以看到pc和c中的vtable指针设置为非零值且它们是相同的。但他们指出的地方充满了零。

恕我直言,它看起来不像vtable指针坏了,看起来像vtable 本身没有被初始化。

1 个答案:

答案 0 :(得分:0)

好的,我发现了问题。为了创建纯粹管理的dll,我使用了这个答案Creating a pure MSIL assembly from a C++/CLI project?

第6步建议添加此代码段:

#pragma warning(disable:4483)
void __clrcall __identifier(".cctor")() { }

我对C#不是很好,所以我只是在没有任何理解的情况下复制它。在这一点上摆脱了一些错误,所以当所有内容构建时我只是把它留在那里而忽略了这样的警告(因为我不能谷歌任何关于它们的东西):

Warning LNK4210 .CRTMA section exists; there may be unhandled static initializers or terminators 

(我知道我应该在问题中提到它,但是很容易忘记忽略警告。忽略警告很糟糕,m&#39; kay?)

Apparanetly这个东西被称为&#39;模块contstructor&#39;它做了许多重要的事情,比如初始化全局变量和静态变量,以及对于特定的事情,vtable。

看起来这个答案的作者并没有使用任何那么空洞的ctor为他工作。

我刚删除了这个空模块ctor,现在vtable不是空的。