gpt4 book ai didi

c# - 使用 dllimport 从 C# 代码更新 C dll 结构数组及其元素值

转载 作者:行者123 更新时间:2023-11-30 22:07:28 26 4
gpt4 key购买 nike

我有 C 代码,它将被构建为一个动态库 (DLL),我想要使用从 C 代码创建的 dLL 从 C# 调用 C 函数

C 代码:

struct data
{
char data_val1[100];
float data_val2;
float data_val3[50];
};
typedef struct data data;

#ifdef __cplusplus
extern "C" __declspec(dllexport) void cfun_call(data *pdata,long count);
#endif

#ifdef __cplusplus
extern "C"
{
#endif

__declspec(dllexport) void cfun_call(data *pdata,long count)
{
int x = 0;
for(x=0;x<count;x++)
{
data[x].data_val2 = (pdata->data_val3[49] + pdata->data_val3[48]) / 2.0;
}
}
#ifdef __cplusplus
}
#endif

这里我想在 C# 代码中导入函数“cfun_call”,并将值传递给函数调用并从 dll 操作 C 函数中传递的值,并希望显示更新后的值回到 C# 代码并显示它,由于我在 C# 方面的专业知识有限,我需要一些帮助来解决这个问题

C#代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

class Program
{
public class data
{
public char[] data_val1 = new char[100];
public float data_val2;
public float[] data_val3 = new float[50];

};
[DllImport("mycdll.dll", EntryPoint = "cfun_call", CallingConvention = CallingConvention.Cdecl, ExactSpelling = false)]
// void cfun_call(data *pdata,long count); //C function for reference
public static extern void cfun_call([In, Out] data[] ouputdata, long count);
static void Main(string[] args)
{
data[] objData = new data[10];
for (int i = 0; i < 10; i++)
{
//Fill the data in objitemData
objData[i] = new objData();
for (int j = 0; j < 100; j++)
{
objData[i].data_val1[j] = '\0';
}

for (int k = 0; k < 50; k++)
{
objData[i].data_val3[k] = 20.00;
}
objData[i].data_val2 = 0.00;
}

cfun_call(objData,10); //Making call to C dll function

for (int i = 0; i < 10; i++)
Console.WriteLine("{0} ", objData[i].data_val2);

Console.WriteLine("");//new line
Console.ReadLine();

}
}

这里从 C# 函数传递的值 (objData) 没有通过使用 C dll 函数更新,我不确定为什么。谁能指出我正确的方向?

编辑 1:

我已经按照建议更新了代码,

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct data
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
public char[] data_val1;
public float data_val2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
public float[] data_val3;
};

初始化结构元素如下,

    data[] objData = new data[10];

for (int i = 0; i < 10; i++)
{
//Fill the data in objitemData
objData[i] = new objData();
for (int j = 0; j < 100; j++)
{
objData[i].data_val1[j] = '\0'; //I am getting exception here
}

for (int k = 0; k < 50; k++)
{
objData[i].data_val3[k] = 20.00;
}
objData[i].data_val2 = 0.00;
}

运行时我得到 null ptr 异常,比如

在 mybinary.exe 中发生类型为“System.NullReferenceException”的未处理异常

附加信息:未将对象引用设置为对象的实例。

如何在托管代码中正确初始化结构数组元素?

编辑 2:

你好还有一个问题,当我添加时,objData[i].data_val3[k] = randomData;//randomvalues,当使用 contnt 值进行 cfun_call 时,它不会更新,为什么会更新?

最佳答案

您对结构的翻译不正确。你需要它像这样:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct data
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
public char[] data_val1;
public float data_val2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
public float[] data_val3;
};

您必须将其设为结构,因为您需要传递一组值。您使用类的声明会导致您传递一个引用数组。

您现在需要明确地初始化数组。这可能看起来像这样:

data[] objData = new data[10];
for (int i = 0; i < 10; i++)
{
objData[i].data_val1 = new char[100];
objData[i].data_val2 = 0.00;
objData[i].data_val3 = new float[50];
for (int k = 0; k < 50; k++)
{
objData[i].data_val3[k] = 20.0f;
}
}

此外,C++ long 是 32 位宽,而 C# long 是 64 位宽。因此,您不匹配。你的 p/invoke 应该是:

[DllImport("mycdll.dll", CallingConvention = CallingConvention.Cdecl)] 
public static extern void cfun_call(
[In, Out] data[] ouputItem_data,
int count
);

关于c# - 使用 dllimport 从 C# 代码更新 C dll 结构数组及其元素值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22983869/

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