gpt4 book ai didi

c# - 从 C# 将数据传入和传出 DLL

转载 作者:太空宇宙 更新时间:2023-11-04 03:18:27 26 4
gpt4 key购买 nike

我正在尝试创建一个 C# 程序,该程序可以将数据传递到 C/C++ DLL、存储数据并在其上完成计算。然后将结果返回给 C# 程序。不使用 C# 进行计算的原因是我计划使用 CUDA 对其进行加速。

我目前在 C# 中声明一个字节数组,并将其作为参数传递给 DLL 以发送数据。

然后,我在 C# 中声明了一个相同大小的字节数组,并将其作为参数传递以接收数据。然后 DLL 应将结果写入该内存。

当我运行程序时,正确的数字被打印到屏幕上。 (因为我将 1,2,3... 写入数组两次,所以它们的加法是 2,4,6...)然后打印“The cat chased the mouse”。当我按下某个键时,会显示“The mouse chased the cat”,程序在退出前崩溃并显示 vshost32.exe 已停止工作错误。我能够从 this question 解决这个错误.

现在,当我尝试直接从 Windows 资源管理器运行 EXE 时,第一步打印出数字 36,但随后在计算函数调用中出现以下错误:

"Unhanded exception: System.AccessViolationException Attempted to read or write protected memory. This is often an indication that other memory is corrupt"

我知道 DLL 已正确加载,因为 init 函数返回了正确的数字。我不确定为什么它只会在我将它作为 EXE 而不是在调试器中运行时崩溃。可能是什么原因造成的?

我应该用不同的方式来处理 DLL 和 C# 程序之间的内存交换吗?我的目标是避免使用 Marshal Copy 复制它,因为我需要它具有高性能。最终目标是 DLL 将内存复制到 GPU 或从 GPU 复制内存,GPU 进行计算,所以我认为没有理由在转到 GPU 之前在 DLL 中复制它第二次。

C++ DLL 代码(写成 C 代码)

#include "stdafx.h"  
#include "stdlib.h"
const int CONSTANT = 3;
char** items;
int itemCount = 0;
int xcnt = -1;
int ycnt = -1;

extern "C" int __declspec(dllexport) __stdcall init(int itemcount_local, int xcnt_local, int ycnt_local){
itemCount = itemcount_local;
xcnt = xcnt_local;
ycnt = ycnt_local;
items = (char**)malloc(itemCount);
if (items == NULL){
return -1;
}
for (int i = 0; i < itemCount; i++){
items[i] = (char*)malloc(CONSTANT*xcnt*ycnt);
if (items[i] == NULL){
return -1;
}
for (int d = 0; d < CONSTANT*xcnt*ycnt; d++){
items[i][d] = 0;
}
}
return CONSTANT*xcnt*ycnt;
}

//frees the memory created in init
extern "C" void __declspec(dllexport) __stdcall cleanup(){
for (int i = 0; i < itemCount; i++){
free(items[i]);
}
free(items);
return;
}

extern "C" void __declspec(dllexport) __stdcall loadItem(int index, char* data){
memcpy(items[index], data, CONSTANT*xcnt*ycnt);
return;
}

//fills the buffer with the computed result. Buffer needs to be the size of CONSTANT*xcnt*ycnt
extern "C" void __declspec(dllexport) __stdcall compute(char* buffer){
for (int x = 0; x < CONSTANT*xcnt*ycnt; x++){
int sum = 0;
for (int i = 0; i < itemCount; i++){
sum += items[i][x];
}
if (sum > 255){ //saturate at 255
buffer[x] = 255;
}
else {
buffer[x] = sum;
}
}
return;
}

C#代码

class Program
{
[DllImport("DllTest1.dll", CallingConvention=CallingConvention.StdCall, SetLastError = true, CharSet = CharSet.Ansi)]
public static extern int init(int imagecount_local, int xres_local, int yres_local);

[DllImport("DllTest1.dll", CallingConvention=CallingConvention.StdCall, SetLastError = true, CharSet = CharSet.Ansi)]
public static extern void cleanup();

[DllImport("DllTest1.dll", CallingConvention=CallingConvention.StdCall, SetLastError = true, CharSet = CharSet.Ansi)]
public static extern void loadItem(int index, byte[] data);

[DllImport("DllTest1.dll", CallingConvention=CallingConvention.StdCall, SetLastError = true, CharSet = CharSet.Ansi)]
public static extern void compute(byte[] buffer);

static void Main(string[] args)
{

int x = 4, y = 3;
int total = x * y * 3;
Console.WriteLine(init(5, x, y));

byte[] a = new byte[total];

compute(a);
for (int i = 0; i < total; i++)
{
Console.WriteLine(a[i]);
}

byte[] b = new byte[total];
for (int i = 0; i < total; i++)
{
b[i] = (byte)i;
}
loadItem(0, b);
loadItem(1, b);

compute(a);
for (int i = 0; i < total; i++)
{
Console.WriteLine(a[i]);
}

//cleanup();
Console.WriteLine("The cat chased the mouse");
Console.ReadKey();
Console.WriteLine("The mouse chased the cat");
return;
}
}

最佳答案

我能够解决问题。线路

items = (char**)malloc(itemCount);

应该是

items = (char**)malloc(itemCount*sizeof(char*));

关于c# - 从 C# 将数据传入和传出 DLL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49040496/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com