C中void指针类型转换到C#的问题.
我用C#调用C编译的dll中有这样一个函数,函数大概的功能就是把数据保存到buf缓冲区中:int retrieve(int scanno,void* buf);
在C中是通过先定义一个结构体再调用这个函数的:
#define COUNT_DIMENSION_MAX 256
typedef struct tagVECTOR_st {
int dimension;
double vector[COUNT_DIMENSION_MAX];
} VECTOR_st;
struct tagSample_st {
int ID;
VECTOR_st Vec; //
} rec;
retrieveall(scanno,&rec);
请问各位大牛,这个retrieve函数的参数void* buf在C#中应该转换成什么?C#中并不能定义void*,我查找过一些资料,貌似说是转换成IntPtr,
public static extern int retrieveall(int scanno, IntPtr buf);
但是在C#中调用的时候应该传递什么样的参数给buf呢?C#中又不能写成&rec这种形式。希望大家帮忙解答!谢谢各位! --------------------编程问答-------------------- 如果是.net4可以使用dynamic 类型再转换 --------------------编程问答--------------------
C#中的IntPtr类型称为“平台特定的整数类型”,它们用于本机资源,如窗口句柄。
资源的大小取决于使用的硬件和操作系统,但其大小总是足以包含系统的指针(因此也可以包含资源的名称)。
举个例子
[DllImport("winmm.dll")]
private static extern long mciSendString(string a,string b,uint c,IntPtr d);
然后用这样的方法调用:
mciSendString("set cdaudio door open", null, 0, this.Handle);
您也可以使用IntPtr.Zero将句柄设置为0;
或者使用类型强制转换:
mciSendString("set cdaudio door open", null, 0, (IntPtr)0 );
或者,使用IntPtr构造函数:
IntPtr a = new IntPtr(2121); --------------------编程问答-------------------- C和C++中的结构要转换到C#中,要在C#中重新定义这个C或者C++的结构,后通过指针转换到结构。 --------------------编程问答--------------------
我知道要在C#中重新定义结构了,关键在于我不知道int retrieve(int scanno,void* buf)这个函数在C#中怎么声明,因为C#没办法把函数的参数声明成void* buf --------------------编程问答--------------------
是应该用void*C#对应的就是IntPtr啊 --------------------编程问答-------------------- 传结构体嘛。
--------------------编程问答-------------------- 用IntPtr也是可以的,但这样需要自行申请和释放非托管内存
建议的方法是定义为ref tagSample_st buffer,即使用引用传递tagSample_st结构,这相当于向C传递该tagSample_st结构的指针 --------------------编程问答-------------------- struct tagSample_st {
int ID;
VECTOR_st Vec; //
} rec;
这不是个结构吗,你用类来写,试试传引用 --------------------编程问答--------------------
由于这个函数int retrieve(int scanno,void* buf)是用于读取数据库中某一个表中某条记录的所有字段,而数据库中不同表拥有的字段也是不同的(那个struct结构体就是用来定义一个表中的每个字段的),所以并不能将参数声明成统一的结构体,只能声明成一个指针。
那么如果只能用IntPtr的话,如何自行申请和释放非托管内存? --------------------编程问答-------------------- 以tagSample_st为例:
public partial class LibWrap
{
const int COUNT_DIMENSION_MAX = 256;
[StructLayout(LayoutKind.Sequential)]
public struct tagVECTOR_st
{
int dimension;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = COUNT_DIMENSION_MAX)]
double[] vector;
}
[StructLayout(LayoutKind.Sequential)]
public struct tagSample_st
{
int ID;
tagVECTOR_st Vec;
}
[DllImport("MyDll.dll")]
public static extern int retrieveall(int scanno, IntPtr buf);
}
LibWrap.tagSample_st rec = new LibWrap.tagSample_st();
int cb = Marshal.SizeOf(typeof(LibWrap.tagSample_st));
IntPtr ptr = Marshal.AllocCoTaskMem(cb);
//Marshal.StructureToPtr(rec, ptr, true);
int iResult = LibWrap.retrieveall(0, ptr);
Marshal.PtrToStructure(ptr, rec);
Marshal.FreeCoTaskMem(ptr);
其实如果不同的表,对应不同的字段,定义不同的结构,也可以利用函数重载,使用ref
补充:.NET技术 , C#