如何在 C# 中封送结构数组?
我必须在 C# 中调用 C++ dll。 dll 的标头如下(简化):
//C++ 标头
struct vector
{
float x;
float y;
vector()
{}
vector(float x0, float y0)
{
x = x0;
y = y0;
}
};
struct unmanaged_struct
{
int int_var;
float float_var;
char* chars_var;
vector vector_var;
unmanaged_struct(int i, float f, char* ch, float vec_x, float vec_y)
{
int_var = i;
float_var = f;
chars_var = ch;
vector_var = vector(vec_x, vec_y);
}
};
// 此函数用于输出结构体实例的所有变量值
extern "C" __declspec( dllexport ) void unmanagedstruct_summary(unmanaged_struct* us_list, int length);
我在 C# 中定义了以下类
//CSharp
[StructLayout(LayoutKind.Sequential)]
public class Vector
{
public float x;
public float y;
public Vector(float f1, float f2)
{
x = f1;
y = f2;
}
}
[StructLayout(LayoutKind.Sequential)]
public class UnmanagedStruct
{
public int int_var;
public float float_var;
public string char_var;
public Vector vector_var;
public UnmanagedStruct(int i, float f, string s, Vector vec)
{
this.int_var = i;
this.float_var = f;
this.char_var = s;
this.vector_var = vec;
}
}
class UnmanagedDllCallTest
{
[DllImport("unmanageddll.dll", EntryPoint = "unmanagedstruct_summary")]
public static extern void unmanagedstruct_summary([Out]UnmanagedStruct[] usList, int length);
static void Main(string[] args)
{
UnmanagedStruct[] usList = new UnmanagedStruct[1];
usList[0] = new UnmanagedStruct(1, 1.0f, "aa", new Vector(10, 1));
usList[1] = new UnmanagedStruct(2, 2.0f, "ba", new Vector(20, 2));
UnmanagedDllCallTest.unmanagedstruct_summary(usList, 2);
}
输出如下:
unmanaged_struct摘要:
0
1.12104e-044
未处理的异常: System.AccessViolationException: 尝试读或写保护 记忆。这通常是一个迹象 其他内存已损坏。在 callunmanageddll.UnmanagedDllCallTest.unmanagementstruct_summary(UnmanagementStr uct[] usList,Int32 长度)位于 调用unmanageddll.Program.Main(String[] args) 在 c:\users\dynaturtle\docume 中 nts\视觉工作室 2010\项目\callunmanagementdll\callunmanagementdll\Program.cs:lin 68
C++ dll 没问题,因为我已经用 C++ 编写了测试,并且该功能运行良好。我已阅读此线程,但解决方案似乎没有'在我的情况下不起作用。有什么建议吗?提前致谢!
I have to call a C++ dll in C#. And the header of the dll is as following(simplified):
//Header of C++
struct vector
{
float x;
float y;
vector()
{}
vector(float x0, float y0)
{
x = x0;
y = y0;
}
};
struct unmanaged_struct
{
int int_var;
float float_var;
char* chars_var;
vector vector_var;
unmanaged_struct(int i, float f, char* ch, float vec_x, float vec_y)
{
int_var = i;
float_var = f;
chars_var = ch;
vector_var = vector(vec_x, vec_y);
}
};
// this function is used to output all the variable values of the struct instance
extern "C" __declspec( dllexport ) void unmanagedstruct_summary(unmanaged_struct* us_list, int length);
And I defined following class in C#
//CSharp
[StructLayout(LayoutKind.Sequential)]
public class Vector
{
public float x;
public float y;
public Vector(float f1, float f2)
{
x = f1;
y = f2;
}
}
[StructLayout(LayoutKind.Sequential)]
public class UnmanagedStruct
{
public int int_var;
public float float_var;
public string char_var;
public Vector vector_var;
public UnmanagedStruct(int i, float f, string s, Vector vec)
{
this.int_var = i;
this.float_var = f;
this.char_var = s;
this.vector_var = vec;
}
}
class UnmanagedDllCallTest
{
[DllImport("unmanageddll.dll", EntryPoint = "unmanagedstruct_summary")]
public static extern void unmanagedstruct_summary([Out]UnmanagedStruct[] usList, int length);
static void Main(string[] args)
{
UnmanagedStruct[] usList = new UnmanagedStruct[1];
usList[0] = new UnmanagedStruct(1, 1.0f, "aa", new Vector(10, 1));
usList[1] = new UnmanagedStruct(2, 2.0f, "ba", new Vector(20, 2));
UnmanagedDllCallTest.unmanagedstruct_summary(usList, 2);
}
And the output is as following:
unmanaged_struct summary:
0
1.12104e-044
Unhandled Exception:
System.AccessViolationException:
Attempted to read or write protected
memory. This is often an indication
that other memory is corrupt. at
callunmanageddll.UnmanagedDllCallTest.unmanagedstruct_summary(UnmanagedStr
uct[] usList, Int32 length) at
callunmanageddll.Program.Main(String[]
args) in c:\users\dynaturtle\docume
nts\visual studio
2010\Projects\callunmanageddll\callunmanageddll\Program.cs:lin
e 68
The C++ dll is OK as I have written test in C++ and the function works well. I have read this thread but it seems the solution didn't work in my case. Any suggestions? Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用Marshal.PtrToStructure。这里有一个示例。
因此,您必须将方法的签名从 out 结构数组更改为 out IntPtr。但是,您需要知道正在传递的缓冲区的大小。
Use
Marshal.PtrToStructure
. There is a sample here.So you would have to change the signature of the method from out structure array to out IntPtr. However, you need to know the size of the buffer being passed out.
第一:Vector 和 UnmanagedStruct 应该是结构体,而不是类。
First: Vector and UnmanagedStruct should be structs, not classes.
JIC 我会分享我的方法。也许这不是我花时间解决我的问题所期望的答案。
我有以下结构来公开 DLL 中的一些数据。
要从 C++ 接受此数据,我可以这样做
要在 C# 上执行相同的操作,我使用以下方法
,我看到有不同的方法来执行此操作。这是其中之一。这对我有用。也许这篇文章不能解决问题,但将是一个很好的起点
JIC I'd share my approach. Perhaps this is not an expected answer by at one time I spend a time to resolve my issue.
I have the following structure to expose some data from DLL.
To accept this data From C++ I can do this way
To do the same on C# I used the following way
As, I saw the are different approaches to do this. This is one of them. And it works for me. Perhaps, this post will not resolve the issue but will be a good point to start