Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用DLLImport将数据发送到非托管代码 我在C++代码中有以下签名 extern "C" __declspec(dllexport) void*__cdecl widgetCreate(char* data, size_t length){ return new Widget(data); }_C#_C++_Interop - Fatal编程技术网

C# 使用DLLImport将数据发送到非托管代码 我在C++代码中有以下签名 extern "C" __declspec(dllexport) void*__cdecl widgetCreate(char* data, size_t length){ return new Widget(data); }

C# 使用DLLImport将数据发送到非托管代码 我在C++代码中有以下签名 extern "C" __declspec(dllexport) void*__cdecl widgetCreate(char* data, size_t length){ return new Widget(data); },c#,c++,interop,C#,C++,Interop,在我的C#代码中: < >我希望C++代码保留自己的代码< >数据>代码>,所以我做了 MycPy.()/< >: 有没有办法让执法官帮我复印?像下面这样的 [DllImport(Path, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr widgetCreate([CopyThisThing] byte[] data); 不,那份拷贝迟早要再发布一次。pinvoke封送拆收器无法知道本机代码使

在我的C#代码中:

< >我希望C++代码保留自己的代码< >数据>代码>,所以我做了<代码> MycPy.()/< >: 有没有办法让执法官帮我复印?像下面这样的

[DllImport(Path, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr widgetCreate([CopyThisThing] byte[] data);

不,那份拷贝迟早要再发布一次。pinvoke封送拆收器无法知道本机代码使用哪个分配器。因此,它无法可靠地选择堆来存储副本。只有使用UnmanagedType.SafeArray的[Marshallas]才能写入以强制创建副本。为使互操作安全而创建的特定数组类型,通常仅由显式编写以支持互操作的代码接受。像COM代码一样,您通常不会使用pinvoke

在某些情况下,当托管数据不可Blitttable且需要按照[StructLayout]的指示从托管布局转换为本机布局时,它必须进行复制。但是,这是完全透明的,封送员将始终在调用完成后删除副本

您可以通过在C代码中显式创建副本来实现。将参数声明为IntPtr,并使用Marshal.AllocHGlobal()或Marshal.allocTaskMem()分配内存。并自行封送数据,通常是通过调用marshal.StructureToPtr()进行封送。除非您知道本机代码使用适当的方式再次释放副本,否则这样做的可能性不大。换句话说,LocalFree()或CoTaskMemFree()。如果对本机代码使用VS2012或更高版本,则可能性会显著增加,其CRT现在使用默认进程堆,而不是创建自己的堆

extern "C" __declspec(dllexport) void*__cdecl 
widgetCreate(char* data, size_t length){
    auto copy = new char[length];
    memcpy(copy, data, length);
    return new Widget(copy);
}
[DllImport(Path, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr widgetCreate([CopyThisThing] byte[] data);