gpt4 book ai didi

c# - 将包含 int 和 int[] 的结构从 C# 编码到 C++

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:11:50 26 4
gpt4 key购买 nike

我有一个带有非托管代码的 C++ DLL 和一个 C# UI。有一个从 C++ DLL 导入的函数,它以我编写的结构作为参数。

将我编写的结构 (MyImage) 从 C# 编码到 C++ 后,我可以访问其中的 int[] 数组的内容,但内容不同。我不知道我在这里遗漏了什么,因为我花了很多时间并尝试了一些技巧来解决这个问题(显然还不够)。

C# 中的 MyImage 结构:

[StructLayout(LayoutKind.Sequential)]
struct MyImage
{
public int width;
public int height;
public int[] bits; //these represent colors of image - 4 bytes for each pixel
}

C++ 中的 MyImage 结构:

struct MyImage
{
int width;
int height;
Color* bits; //typedef unsigned int Color;

MyImage(int w, int h)
{
bits = new Color[w*h];
}

Color GetPixel(int x, int y)
{
if (x or y out of image bounds) return UNDEFINED_COLOR;
return bits[y*width+x];
}
}

以 MyImage 作为参数的 C# 函数声明:

[DLLImport("G_DLL.dll")]
public static extern void DisplayImageInPolygon(Point[] p, int n, MyImage texture,
int tex_x0, int tex_y0);

C++实现

DLLEXPORT void __stdcall DisplayImageInPolygon(Point *p, int n, MyImage img,
int imgx0, int imgy0)
{
//And below they have improper values (i don't know where they come from)
Color test1 = img.GetPixel(0,0);
Color test2 = img.GetPixel(1,0);
}

因此,在调试问题时,我注意到 C++ 结构中的 MyImage.bits 数组包含不同的数据。

我该如何解决?

最佳答案

由于 bits 字段是指向在 native 代码中分配的内存的指针,因此您需要在 C# 代码中将其声明为 IntPtr

struct MyImage
{
public int width;
public int height;
public IntPtr bits;
}

如果您想访问 C# 代码中的单个像素,您需要编写一个 GetPixel 方法,就像您在 C++ 代码中所做的那样。

请注意,由于 bits 字段是指向在 native 代码中分配的内存的指针,我希望实际代码具有调用 delete[] bits 的结构的析构函数。否则你的代码将会泄露。

这也意味着您将需要在 native 代码中创建和销毁实例,而永远不要在托管代码中这样做。这是您目前遵循的政策吗?我怀疑不是基于我在这里看到的代码。

您还需要重新考虑按值传递 struct。当你调用那个函数时,你真的想复制它吗?这样做意味着您有两个结构实例,它们的 bits 字段都指向同一内存。但是,谁拥有那段内存?这个结构确实需要通过引用传递。

我认为您的设计存在一些问题,但我看不到足够多的代码,或者对您的问题了解不够,无法给您具体的建议。


在评论中,您声明您的主要目标是将这些位从您的 C# 代码传输到 C++ 代码。我建议你这样做:

MyImage* NewImage(int w, int h, Color* bits)
{
MyImage* img = new MyImage;
img->w = w;
img->h = h;
img->bits = new Color[w*h];
for (int i=0; i<w*h; i++)
img->bits[i] = bits[i];
return img;
}

void DeleteImage(MyImage* img)
{
delete[] img->bits;
delete img;
}

void DoSomethingWithImage(MyImage* img)
{
// do whatever it is you need to do
}

在 C# 端,您可以这样声明它:

[DllImport(@"dllname.dll", CallingConvention=CallingConvention.Cdecl)]
static extern IntPtr NewImage(int w, int h, int[] bits);

[DllImport(@"dllname.dll", CallingConvention=CallingConvention.Cdecl)]
static extern void DeleteImage(ImtPtr img);

[DllImport(@"dllname.dll", CallingConvention=CallingConvention.Cdecl)]
static extern void DoSomethingWithImage(ImtPtr img);

关于c# - 将包含 int 和 int[] 的结构从 C# 编码到 C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13504195/

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