【发布时间】:2014-07-29 07:58:26
【问题描述】:
我使用来自 C# 的本机 C++ 代码库,以及围绕它构建的 C++/CLI 包装器(使用 Visual Studio 2013)。有两个项目:
- NativeCodeBase:简单的 C++ 项目集构建到静态库中。
- ManagedWrapper:C++/CLI 项目引用 NativeCodeBase。
我在 NativeCodeBase 中有以下原生“接口”:
class ITest {
virtual void Foo(const std::string& str, MyEnum me) = 0;
}
为此,我在 ManagedWrapper 项目中有一个本机实现。
在标题中:
class TestManaged : public ITest {
virtual void Foo(const std::string& str, MyEnum me) override;
}
在cpp中:
void TestManaged::Foo(const std::string& str, MyEnum me) {
int length = str.length();
}
MyEnum 枚举在本机代码和托管代码中都使用,因此在其实现中,我使用条件编译的 C++/CLI 扩展,使其可在 C# 中使用:
#ifdef _MANAGED
public
#endif
enum class MyEnum : unsigned char
{
Baz = 0,
Qux = 1
};
在我的本机代码中,我引用了 ITest 并使用本地 std::string 变量调用其 Foo 函数。当调用 Foo 时,我可以在调试器中看到作为参数传递的字符串是一个有效的字符串对象。
调用类似这样:
void Bar(ITest& test) {
std::string str = "test";
test.Foo(str, MyEnum::Baz);
}
但是,如果我在 TestManaged::Foo 的开头放置一个断点,调试器会说 str 具有 <undefined value>,并且 length() 调用崩溃,并在以下函数的 <xstring> 标头中出现未定义的引用错误:
size_type length() const _NOEXCEPT
{ // return length of sequence
return (this->_Mysize);
}
调试器也会为this 指针显示<undefined value>。
这可能是什么原因?引用在两个库之间传递时会以某种方式损坏?
(附加信息:我以前不将 NativeCodeBase 项目构建为单独的库,而是将其中的所有源文件链接到 CLI 项目中,并且相同的代码库可以正常工作。自从我配置它后它开始失败被构建到一个单独的库中,并在 CLI 项目中添加了对本机项目的引用。)
【问题讨论】:
-
是否有任何运行时问题(即在调试器中执行之外)?
-
“未定义的引用错误”很难解释。但这里的基本诊断是 std::string 定义在分隔的两端都不相同。使用不同设置或不同版本的 C++ 库编译代码的副作用。迭代器调试始终是一个强有力的候选者,一个但不是另一个。
-
真正的函数还有其他参数,比如第二个参数是一个float,也被破坏了,它在被调用方包含一些乱码。
-
我发现了问题,详细回答中。
标签: c++ visual-c++ visual-studio-2013 c++-cli