我使用C#的本机C ++代码库,围绕它构建了C ++ / CLI包装器(使用Visual Studio 2013)。有两个项目:
我有以下原生"界面"在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
并使用本地Foo
变量调用其std::string
函数。调用Foo时,我可以在调试器中看到作为参数传递的字符串是一个有效的字符串对象。
这个电话类似于:
void Bar(ITest& test) {
std::string str = "test";
test.Foo(str, MyEnum::Baz);
}
但是,如果我在TestManaged::Foo
的开头放置一个断点,调试器会说str有<undefined value>
,并且length()
调用在{{1}中因未定义的引用错误而崩溃以下函数中的标题:
<xstring>
调试器也会为size_type length() const _NOEXCEPT
{ // return length of sequence
return (this->_Mysize);
}
指针显示<undefined value>
。
这可能是什么原因?在两个库之间传递时,引用会以某种方式被破坏?
(附加信息:我不是将NativeCodeBase项目构建为单独的lib,而是将其中的所有源文件链接到CLI项目中,并且相同的代码库没有任何问题。由于我配置了它,它开始失败要构建到单独的lib中,并将CLI项目中的引用添加到本机库中。)
答案 0 :(得分:-1)
问题不在于引用本身。问题出在第二个枚举参数上。枚举类的实现看起来像这样:
#ifdef _MANAGED
public
#endif
enum class MyEnum : unsigned char
{
Baz = 0,
Qux = 1
};
为了在为本机C ++构建时创建一个本地枚举,将#ifdef指令放在那里,但是在为C ++ / CLI构建时创建一个CLI枚举。
当所有源文件都链接到CLI项目并且每个源代码都是为CLI项目再次构建时,这很有效。但是,当我想从CLI端使用本机lib时,这种方法不再起作用。
我想问题是在两个库中构建了相同的头文件,因此调用者和调用者看到了对象的不同二进制接口,因此参数在传递时会出现乱码。这是对的吗?
我摆脱了有条件编译的public关键字,它又开始正常工作了。