处理c#中指向结构的指针
Handling pointers to structure in C#
我正在做一个项目,其中包括用c++编写的DLL和c#代码。假设DLL有一个函数:
MyStruct* GetPointer(); // returns pointer to MyStruct structure
MyStruct结构如下所示:
struct MyStruct
{
OtherStruct1 *data1;
OtherStruct2 *data2;
};
和OtherStruct1和OtherStruct2结构看起来像这样:
struct OtherStruct1
{
public:
double x;
char y;
};
struct OtherStruct2
{
public:
float a;
float b;
float c;
float d;
};
我的问题是——在c#代码中处理所有这些指针的最好方法是什么?所谓"处理"是指从存储器中读取和写入的操作。c#中的结构不能简单地包含指针变量。我该怎么办?最优雅的方式是什么?
您可以使用Microsoft(现在是开源的)PInvoke互操作助手工具将您的C/c++代码转换为c#或VB。运行示例代码将得到:
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct MyStruct {
/// OtherStruct1*
public System.IntPtr data1;
/// OtherStruct2*
public System.IntPtr data2;
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct OtherStruct1 {
/// double
public double x;
/// char
public byte y;
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct OtherStruct2 {
/// float
public float a;
/// float
public float b;
/// float
public float c;
/// float
public float d;
}
public partial class NativeMethods {
/// Return Type: MyStruct*
[System.Runtime.InteropServices.DllImportAttribute("<Unknown>", EntryPoint="GetPointer")]
public static extern System.IntPtr GetPointer() ;
}
将DllImportAttribute中的"Unknown"替换为您的dll名称,并确保它在项目中被引用。现在您应该能够在托管代码中访问您的结构了。
然后,要从内存中读写,你需要使用System.Runtime.InteropServices.Marshal命名空间中的方法。下面的代码片段展示了如何使用GetPointer函数将非托管结构体转换为托管结构体:
IntPtr myPtr = NativeMethods.GetPointer(); // Call native code to retrieve pointer to unmanaged memory where the struct lives
MyStruct myStruct = new MyStruct(); // Create a new managed struct
myStruct = Marshal.PtrToStructure<MyStruct>(myPtr);
下面是如何将托管结构传递给非托管方法:
MyStruct myStruct = new MyStruct(); // Create the managed struct
myStruct.data1 = new OtherStruct1(); // Create a managed OtherStruct1
myStruct.data2 = new OtherStruct2(); // Create a managed OtherStruct2
IntPtr myStructPtr = Marshal.AllocHGlobal(Marshal.SizeOf<MyStruct>()); // Allocate unmanaged memory for the struct
Marshal.StructureToPtr<MyStruct>(myStruct, myStructPtr, false);
try
{
NativeMethodThatUsesMyStructPtr(myStructPtr);
}
finally
{
Marshal.FreeHGlobal(myStructPtr); // *** You have to free unmanaged memory manually, or you will get a memory leak! ***
}
好的,我想到了一个方法。
[StructLayout(LayoutKind.Sequential)]
struct MyStruct
{
OtherStruct1 *data1;
OtherStruct2 *data2;
};
[StructLayout(LayoutKind.Sequential)]
struct OtherStruct1
{
public:
double x;
char y;
};
[StructLayout(LayoutKind.Sequential)]
struct OtherStruct2
{
public:
float a;
float b;
float c;
float d;
};
然后:
unsafe
{
MyStruct *tmp = (MyStruct*) GetPointer();
tmp->data2[0].a = 1.0F;
}
[DllImport(DLL_PATH, CallingConvention = CallingConvention.Cdecl)]
unsafe public static extern MyStruct* GetPointer();
很有魅力。:)
相关文章:
- 如何在 C# 中映射双 C 结构指针?
- C++:映射结构中的结构指针
- C++:添加新结构时,结构指针向量中的所有元素都会更新
- 类的静态结构指针声明在C++
- 在两个.cpp文件之间定义全局类/结构指针
- 返回对常量结构(指针类型)成员的引用:明显的左值到右值转换
- 是否可以将无符号字符数组reinterpret_cast到仅包含C++中无符号字符成员的结构指针
- 如何在地图中使用结构指针
- 结构指针在"新"调用上给出已分配的地址?
- 铸造结构指针指向C 的工会指针
- c++ 结构指针在初始化为 NULL 时无法读取内存
- 函数中的结构指针的地址为0x1
- C 用结构指针初始化结构
- C 结构指针铸成数组Interop C#
- 方法中不允许访问结构指针
- 如何打印出结构指针
- MPI_Op_create:候选功能不可行.自定义结构指针不能解释为空指针
- 尝试将结构指针传递给类时出错
- 初始化结构指针的值
- 使用 pybind11 将自定义结构(指针向量)从 C++ 传递到 python 的方法是什么?