sách gpt4 ai đã đi

c# - 使用 DLLImport 将数据发送到非托管代码

In lại 作者:行者123 更新时间:2023-11-30 02:48:59 28 4
mua khóa gpt4 Nike

我的 C++ 代码中有以下签名

extern "C" __declspec(dllexport) void*__cdecl 
widgetCreate(char* data, size_t length){
return new Widget(data);
}

以及我的 C# 代码中的以下内容:

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

我希望 C++ 代码保留它自己的 dữ liệu 拷贝,所以我执行了一个 memcpy():

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);

1 Câu trả lời

没有。该拷贝迟早必须再次发布。 pinvoke 编码器不知道 native 代码使用哪个分配器。所以它不能可靠地选择一个堆来存储拷贝。您可以编写以强制制作拷贝的唯一 [MarshalAs] 是使用 UnmanagedType.SafeArray 的一个。为使互操作安全而创建的特定数组类型,通常只被明确编写为支持互操作的代码接受。与 COM 代码一样,您通常不会调用它。

在某些情况下,它phải制作一个拷贝,当托管数据不可 blittable 并且需要按照 [StructLayout] 的指示从托管布局转换为 native 布局时,就会发生这种情况.然而,这是完全透明的,编码器将始终在调用完成后删除拷贝。

BạnCó thể通过在您的 C# 代码中显式创建拷贝来使其工作。您将参数声明为 IntPtr 并使用 Marshal.AllocHGlobal() 或 Marshal.AllocCoTaskMem() 分配内存。并通常通过调用 Marshal.StructureToPtr() 自行编码数据。除非您确实知道 native 代码使用适当的方式再次释放拷贝,否则成功的可能性不大。换句话说,LocalFree() 或 CoTaskMemFree()。如果您对 native 代码使用 VS2012 或更高版本,那么几率会显着增加,它的 CRT 现在使用默认进程堆,而不是创建自己的堆。

关于c# - 使用 DLLImport 将数据发送到非托管代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21656126/

28 4 0
Bài viết được đề xuất: android - 更新 ADT 到最新版本
Bài viết được đề xuất: c++ - 异常保证和快速 push_back
Bài viết được đề xuất: c++ - 向 QDockWidgets 区域添加滚动条
Bài viết được đề xuất: Thuật toán C++ cho cửa sổ trượt trên container
行者123
Hồ sơ cá nhân

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá Didi Taxi miễn phí
Mã giảm giá Didi Taxi
Giấy chứng nhận ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com