C# x64 0xc0000374上的.NET 4.0字符*到字符串互操作崩溃
我目前正在将我们公司的x86软件迁移到x64,遇到了一个障碍。当解决方案平台切换到x64时,从非托管dll返回C# x64 0xc0000374上的.NET 4.0字符*到字符串互操作崩溃,c#,wpf,.net-4.0,pinvoke,32bit-64bit,C#,Wpf,.net 4.0,Pinvoke,32bit 64bit,我目前正在将我们公司的x86软件迁移到x64,遇到了一个障碍。当解决方案平台切换到x64时,从非托管dll返回char*的方法与0xc0000374崩溃,我想知道原因 C++本机代码: #include "stdafx.h" #include <windows.h> #include "windef.h" #define VERSION "3.3.12" extern "C" { __declspec(dllexport) char* WINAPI GetMyVersion()
char*
的方法与0xc0000374崩溃,我想知道原因
C++本机代码:
#include "stdafx.h"
#include <windows.h>
#include "windef.h"
#define VERSION "3.3.12"
extern "C"
{
__declspec(dllexport) char* WINAPI GetMyVersion()
{
return (char*)VERSION;
}
}
GetMyVersionString()
仅在x86平台上工作,在x64平台上崩溃。但是,我能够获取IntPtr
,并使用Marshal
类将其转换为x86和x64上的托管字符串,如下所示:
using System.Runtime.InteropServices;
using System.Windows;
using InteropTest.Adapter;
namespace InteropTest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
var ptr = MyAdapter.GetMyVersionPtr();
var convertedString = Marshal.PtrToStringAnsi(ptr);
// This crashes in x64 build
var directString = MyAdapter.GetMyVersionString();
VersionTextBlock.Text = convertedString;
}
}
}
编辑3:
非托管C++代码是我们的解决方案中的一个项目,X64/x86配置是建立起来的,类似于上面链接的示例项目。
嗯,您的版本不是“字符串”,它确实是指向原始内存的指针。如果您告诉.NET framework该指针是字符串,它将尝试取消分配该指针
因此,您有两种选择:
- 像您一样使用IntPtr,这很好
- 使用COM分配器分配.NET可以理解的一个真正的字符串,因此,在您的情况下,您的C++代码可以被替换为:
注意:您也可以使用BSTR。您得到的异常是什么?您没有说明是否有不同版本的非托管dll(x86/x64)@PatrickHofman我在帖子中添加了关于崩溃的信息。@spender非托管代码是解决方案中的一个项目,并且设置了x86/x64配置。因此CLR假设这是一个返回字符串的DllImported方法,需要使用CoTaskMemFree释放memeory,并为我这样做:但是我们的x86平台上仍然存在不正确的代码。@ChenHuang-不是因为它没有崩溃,它才“工作”。许多臭虫永远活在人们的视线之外。
using System.Runtime.InteropServices;
using System.Windows;
using InteropTest.Adapter;
namespace InteropTest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
var ptr = MyAdapter.GetMyVersionPtr();
var convertedString = Marshal.PtrToStringAnsi(ptr);
// This crashes in x64 build
var directString = MyAdapter.GetMyVersionString();
VersionTextBlock.Text = convertedString;
}
}
}
ntdll.dll!00007ffc0fdc4cfa() Unknown
ntdll.dll!00007ffc0fdcc806() Unknown
ntdll.dll!00007ffc0fdccad1() Unknown
ntdll.dll!00007ffc0fd69a55() Unknown
ntdll.dll!00007ffc0fd77347() Unknown
mscorlib.ni.dll!00007ffbd566759e() Unknown
[Managed to Native Transition]
> InteropTest.exe!InteropTest.MainWindow.OnLoaded(object sender, System.Windows.RoutedEventArgs e) Line 23 C#
PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(object source, System.Windows.RoutedEventArgs args, bool reRaised) Unknown
__declspec(dllexport) char* WINAPI GetMyVersion() {
char* p = (char*)CoTaskMemAlloc(7);
CopyMemory(p, VERSION, 7);
return p;
}