【发布时间】:2012-08-24 15:04:17
【问题描述】:
我正在为原生 c++ 类开发 C++/CLI 包装器。 C++/CLI 包装器正在 WPF 应用程序中使用。我在尝试编组字符串时遇到了一个奇怪的问题。
WPF 应用程序将System::String 对象传递给我的包装器。然后包装器将 System::String 转换为原生类所期望的 std::string。这一切都很好,但是一旦我将字符串传递给本机对象,它就是空的。
这是一些相关的代码
WPF 事件处理程序 (C#)
private void tbInputConfig_TextChanged(object sender, TextChangedEventArgs e)
{
_OrionBasicApp.ConfigTemplateFile = tbInputConfig.Text;
}
包装类中的属性 (C++/CLI)
void BasicApp::ConfigTemplateFile::set(String ^value)
{
std::string val = marshal_as<std::string>(value);
_NativeApp->setConfigTemplateFile(val);
}
本机代码 (C++)
void Basic_App::setConfigTemplateFile(const std::string& template_file)
{
m_gParams.configTemplateFile = template_file;
}
因此,当我中断 WPF 应用程序并使用调试器进行跟踪时,String 对象看起来不错,std::string val 封送看起来不错,但 setConfigFile 函数中的参数 template_file 是一个空字符串。当我退出本机函数时,我可以看到 std::string val 变量看起来仍然很好。
我尝试过使用Marshal::StringToHGlobalAnsi 函数,它产生相同的结果。我尝试更改本机函数以获取字符串的副本而不是引用,这会产生有关无效内存块的异常(如果需要,我将发布确切的消息)。我试过在堆上分配字符串,没有运气。
现在最重要的是:本机代码是用 Microsoft Visual Studio 2008 编译的,而 wrapper + wpf 代码是用 2010 编译的。我希望这不是问题,因为我们将任何一个代码库迁移到都不容易另一个版本。
有什么想法吗?
更新
我能够将本机代码切换到 Visual Studio 2010,这确实解决了问题。 (为什么微软必须让我的生活变得如此困难?)虽然我确实构建了系统,但该项目的负责人给我带来了这个解决方案的主要麻烦(他担心它可能无法正确运行或者我们将不得不切换依赖库)。
那么,这个问题有没有不强制我切换 Visual Studio 版本的解决方案?
【问题讨论】:
-
您的 C++ 是否被编译为 UNICODE、MBCS 或 ANSI ?
-
好问题,我忘了添加此信息。本机代码使用 MultiByte 字符集。我已经在 Unicode 和 MultiByte 中尝试过 C++/CLI 层,这对我的问题没有影响
-
你是如何包装原生代码的?本机代码是在一个 DLL 中,而包装器是在一个单独的 DLL 中,还是链接到一个 DLL 中?
-
本机代码位于 Visual Studio 2009 中内置的单独 dll 中。C++/CLI 从 VS2010 编译为自己的程序集 dll。 WPF 应用程序也从 2010 年开始编译为自己的程序集 exe。理论上,这样每个组件都可以很容易地被不同的来源使用(例如,一些完全基于命令行的原生测试是为原生层编写的)
标签: c# wpf string interop c++-cli