我试图填补结构包含数组从本机库到C#。我的结构包含两个int变量和数组的元素是两个整数的结构。
问题是数组内部的变量被正确接收,但外部结构中的变量被接收为0。如果我在C#端用不同的值初始化它们,它们不会改变。
C接口及实现:
extern "C" {
struct Element
{
int id;
int uid;
};
struct ElementsGrid
{
int width;
int height;
Element* elements;
};
__declspec(dllexport) int gridSize()
{
return 20;
}
__declspec(dllexport) void getGrid(ElementsGrid* grid)
{
grid->width = 5;
grid->height = 4;
for (int w = 0; w < grid->width; ++w) {
for (int h = 0; h < grid->height; ++h) {
int index = w * grid->height + h;
grid->elements[index].uid = index;
grid->elements[index].id = 42;
}
}
}
} // extern "C"
C#部分
[StructLayout(LayoutKind.Sequential)]
public struct Element
{
public int id;
public int uid;
}
[StructLayout(LayoutKind.Sequential)]
public struct ElementsGrid
{
public int width;
public int height;
public Element[] elements;
}
//...
[DllImport("my_plugin")]
static extern void getGrid([In,Out] ElementsGrid ptr);
//...
void getGrid()
{
int field_size = gridSize();
ElementsGrid grid = new ElementsGrid
{
elements = new Element[field_size]
};
getGrid(grid);
print(grid.width); // 0 here. Unchanged
print(grid.height); // 0 here. Unchanged
for (int row = 0; row < 4; row++) {
for (int column = 0; column < 5; column++) {
int index = row * 5 + column;
Element element = grid.elements[index];
print(element.id); // 42. Correct value
print(element.uid); // ==index. Correct value
}
}
}
1条答案
按热度按时间mepcadol1#
这是完全可能的,但您的代码有一些缺陷。C中的getGrid方法需要一个指向ElementsGrid示例的指针,而您试图传递的是示例,而不是指向它的指针。另一个问题是C中ElementsGrid的定义与C#中的等效定义不同;C需要一个指向Element的指针,而C#有一个元素数组。
我根本没有改变你的C代码,但设法让它工作如下。
结构:
当我这样尝试时,getGrid方法可以工作:
读取grid.elements指针到Element数组的新方法。这是必要的,因为你不能在不直接阅读数组的情况下马歇尔指向结构数组的指针。
同样,对于一个空白画布,你可以用一种完全不同的方式来实现这一点,通过改变你在C中的代码来接受行和列的计数,并返回一个指向ElementsGrid结构的指针。C#中的代码可以传入相关的行和列的计数,并从指针中读取数据。这将保存在C#中创建ElementsGrid,获取一个指向它的指针,然后将其传递给你的C代码。
希望这能帮上忙。