C中void指针类型转换到C#的问题.

问题描述

我用C#调用C编译的dll中有这样一个函数,函数大概的功能就是把数据保存到buf缓冲区中:intretrieve(intscanno,void*buf);

在C中是通过先定义一个结构体再调用这个函数的:#defineCOUNT_DIMENSION_MAX256typedefstructtagVECTOR_st{intdimension;doublevector[COUNT_DIMENSION_MAX];}VECTOR_st;structtagSample_st{intID;VECTOR_stVec;//}rec;retrieveall(scanno,&rec);

请问各位大牛,这个retrieve函数的参数void*buf在C#中应该转换成什么?C#中并不能定义void*,我查找过一些资料,貌似说是转换成IntPtr,publicstaticexternintretrieveall(intscanno,IntPtrbuf);

但是在C#中调用的时候应该传递什么样的参数给buf呢?C#中又不能写成&rec这种形式。希望大家帮忙解答!谢谢各位!

解决方案

解决方案二:
如果是.net4可以使用dynamic类型再转换
解决方案三:
引用楼主的回复:

我用C#调用C编译的dll中有这样一个函数,函数大概的功能就是把数据保存到buf缓冲区中:C/C++codeintretrieve(intscanno,void*buf);在C中是通过先定义一个结构体再调用这个函数的:C/C++code#defineCOUNT_DIMENSION_MAX256typedefstructtagVECTOR_s……

C#中的IntPtr类型称为“平台特定的整数类型”,它们用于本机资源,如窗口句柄。资源的大小取决于使用的硬件和操作系统,但其大小总是足以包含系统的指针(因此也可以包含资源的名称)。举个例子[DllImport("winmm.dll")]privatestaticexternlongmciSendString(stringa,stringb,uintc,IntPtrd);然后用这样的方法调用:mciSendString("setcdaudiodooropen",null,0,this.Handle);您也可以使用IntPtr.Zero将句柄设置为0;或者使用类型强制转换:mciSendString("setcdaudiodooropen",null,0,(IntPtr)0);或者,使用IntPtr构造函数:IntPtra=newIntPtr(2121);
解决方案四:
C和C++中的结构要转换到C#中,要在C#中重新定义这个C或者C++的结构,后通过指针转换到结构。
解决方案五:
引用3楼的回复:

C和C++中的结构要转换到C#中,要在C#中重新定义这个C或者C++的结构,后通过指针转换到结构。

我知道要在C#中重新定义结构了,关键在于我不知道intretrieve(intscanno,void*buf)这个函数在C#中怎么声明,因为C#没办法把函数的参数声明成void*buf
解决方案六:
引用4楼的回复:

引用3楼的回复:C和C++中的结构要转换到C#中,要在C#中重新定义这个C或者C++的结构,后通过指针转换到结构。我知道要在C#中重新定义结构了,关键在于我不知道intretrieve(intscanno,void*buf)这个函数在C#中怎么声明,因为C#没办法把函数的参数声明成void*buf

是应该用void*C#对应的就是IntPtr啊
解决方案七:
传结构体嘛。
解决方案八:
用IntPtr也是可以的,但这样需要自行申请和释放非托管内存建议的方法是定义为reftagSample_stbuffer,即使用引用传递tagSample_st结构,这相当于向C传递该tagSample_st结构的指针
解决方案九:
structtagSample_st{intID;VECTOR_stVec;//}rec;这不是个结构吗,你用类来写,试试传引用
解决方案十:
引用7楼的回复:

用IntPtr也是可以的,但这样需要自行申请和释放非托管内存建议的方法是定义为reftagSample_stbuffer,即使用引用传递tagSample_st结构,这相当于向C传递该tagSample_st结构的指针

由于这个函数intretrieve(intscanno,void*buf)是用于读取数据库中某一个表中某条记录的所有字段,而数据库中不同表拥有的字段也是不同的(那个struct结构体就是用来定义一个表中的每个字段的),所以并不能将参数声明成统一的结构体,只能声明成一个指针。那么如果只能用IntPtr的话,如何自行申请和释放非托管内存?
解决方案十一:
以tagSample_st为例:publicpartialclassLibWrap{constintCOUNT_DIMENSION_MAX=256;[StructLayout(LayoutKind.Sequential)]publicstructtagVECTOR_st{intdimension;[MarshalAs(UnmanagedType.ByValArray,SizeConst=COUNT_DIMENSION_MAX)]double[]vector;}[StructLayout(LayoutKind.Sequential)]publicstructtagSample_st{intID;tagVECTOR_stVec;}[DllImport("MyDll.dll")]publicstaticexternintretrieveall(intscanno,IntPtrbuf);}LibWrap.tagSample_strec=newLibWrap.tagSample_st();intcb=Marshal.SizeOf(typeof(LibWrap.tagSample_st));IntPtrptr=Marshal.AllocCoTaskMem(cb);//Marshal.StructureToPtr(rec,ptr,true);intiResult=LibWrap.retrieveall(0,ptr);Marshal.PtrToStructure(ptr,rec);Marshal.FreeCoTaskMem(ptr);

其实如果不同的表,对应不同的字段,定义不同的结构,也可以利用函数重载,使用ref

时间: 2024-10-29 09:24:09

C中void指针类型转换到C#的问题.的相关文章

C++中四种类型转换 const_cast是否能改变常量

we have four specific castingoperators:dynamic_cast, reinterpret_cast, static_cast and const_cast. Their format is to follow the new type enclosed between angle-brackets (<>) and immediately after, the expression to be converted between parentheses.

Swift 中的指针使用

Apple 期望在 Swift 中指针能够尽量减少登场几率,因此在 Swift 中指针被映射为了一个泛型类型,并且还比较抽象.这在一定程度上造成了在 Swift 中指针使用的困难,特别是对那些并不熟悉指针,也没有多少指针操作经验的开发者 (包括我自己也是) 来说,在 Swift 中使用指针确实是一个挑战.在这篇文章里,我希望能从最基本的使用开始,总结一下在 Swift 中使用指针的一些常见方式和场景.这篇文章假定你至少知道指针是什么,如果对指针本身的概念不太清楚的话,可以先看看这篇五分钟 C 指

c++中,const_cast类型转换问题

问题描述 c++中,const_cast类型转换问题 #include using namespace std; void foo(const int a) { int *p = const_cast<int>(a); *p = 10; cout << *a << endl; //输出10 cout << a << endl; } int main() { const int n = 100; foo(&n); cout <<

void及void指针含义的深刻解析

转载地址:http://blog.csdn.net/geekcome/article/details/6249151 void的含义:     void即"无类型",void *则为"无类型指针",可以指向任何数据类型. void指针使用规范:     ①void指针可以指向任意类型的数据,亦即可用任意数据类型的指针对void指针赋值.例如:     int * pint;     void *pvoid;     pvoid = pint; /* 不过不能 pin

C/C++学习 ---- void及void指针含义的深刻解析

 原文转载自:http://blog.csdn.net/geekcome/article/details/6249151 1. void的含义 void即"无类型",void *则为"无类型指针",可以指向任何数据类型. 2. void指针使用规范①void指针可以指向任意类型的数据,亦即可用任意数据类型的指针对void指针赋值.例如: int * pint; void *pvoid; pvoid = pint; /* 不过不能 pint= pvoid; */如果要

Swift中的指针操作和使用详细介绍_Swift

Apple期望在Swift中指针能够尽量减少登场几率,因此在Swift中指针被映射为了一个泛型类型,并且还比较抽象.这在一定程度上造成了在Swift中指针使用的困难,特别是对那些并不熟悉指针,也没有多少指针操作经验的开发者(包括我自己也是)来说,在Swift中使用指针确实是一个挑战.在这篇文章里,我希望能从最基本的使用开始,总结一下在Swift中使用指针的一些常见方式和场景.这篇文章假定你至少知道指针是什么,如果对指针本身的概念不太清楚的话,可以先看看这篇五分钟C指针教程(或者它的中文版本),应

C/C++语言void及void指针《转》

1.概述许多初学者对C/C++语言中的void及void指针类型不甚理解,因此在使用上出现了一些错误.本文将对void关键字的深刻含义进行解说,并详述void及void指针类型的使用方法与技巧.2.void的含义 void的字面意思是"无类型",void *则为"无类型指针",void *可以指向任何类型的数据.void几乎只有"注释"和限制程序的作用,因为从来没有人会定义一个void变量,让我们试着来定义: void a; 这行语句编译时会出错

详解Java中的指针、引用及对象的clone

对象|详解 Java语言的一个优点就是取消了指针的概念,但也导致了许多程序员在编程中常常忽略了对象与引用的区别,本文会试图澄清这一概念.并且由于Java不能通过简单的赋值来解决对象复制的问题,在开发过程中,也常常要要应用clone()方法来复制对象.本文会让你了解什么是影子clone与深度clone,认识它们的区别.优点及缺点.看到这个标题,是不是有点困惑:Java语言明确说明取消了指针,因为指针往往是在带来方便的同时也是导致代码不安全的根源,同时也会使程序的变得非常复杂难以理解,滥用指针写成的

C++中智能指针(smarter pointer)自定义删除器(deleter) 的方法

智能指针包含两种"shared_ptr"和"unique_ptr", 由于两种指针的实现方式不同, 所以传递删除器的方式也不同; "shared_ptr"的传递删除器(deleter)方式比较简单, 只需要在参数中添加具体的删除器函数名, 即可; 注意是单参数函数; "unique_ptr"的删除器是函数模板(function template), 所以需要在模板类型传递删除器的类型(即函数指针(function pointe