c#调用C、C++编写的dll
1为了使c能调用c++写的dll。c++中使用extern "C"{ }修饰该接口即可
这个原因你应该知道吧大概意思是告诉c++编译器这段代码用c编译器编译
编译之后的结果是c方式的而不是c++方式的。
2但是c中不识别extern "C"。
综上两点,在dll头文件中常这样写,如下:
意思就是编译的时候编译成c方式。但是包含头文件时,因为是c调用所以会忽略掉extern "C"
#ifdef __cplusplus
extern "C"
{
#endif
。。。。。。。。。。。。
#ifdef __cplusplus
}
#endif
这个你也明白吧。
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
这个问题 我可以非常明确地告诉你,C#无法直接调用这种参数的函数,C#中你描述的那种二维数组,本质上跟一维数组一致。倒是single[][]跟float**是类似的,但是也不能直接传递。
然后具体说说
float* arr arr为指向float型的指针
single[] arr arr为single型数组的引用,当传递给API时,会自动传递内部指针,这个指针才真真的指向single型的指针
float** arr arr为一个指向float型指针的指针,即arr[]应该是一个float型指针
single[][] arr arr为一个single型数组引用的数组引用,这意味着arr的内部指针指向的是single[]型引用的指针,跟指向single型指针完全是两码事
综上所述,C#不能直接调用Test(float** arr,int rows,int cols),你必须使用非安全代码构造一个single*[],然后将这个数组传递过去。下面是一个例子
[DllImport("test.dll")]
static extern unsafe bool Test(float*[] arr, int row, int col);//这里arr要声明为float*[],使用起来比较方便
bool CallTest(float[,] arr)
{
int row = arr.GetUpperBound(0) + 1;
int col = arr.GetUpperBound(1) + 1;
unsafe
{
fixed(float* fp=arr)
{
float*[] farr=new float*[row];
for (int i = 0; i < row;i++ )
{
farr[i] = fp + i * col;
}
return Test(farr, row, col);
//如果Test(float** arr, int row, int col)这样声明,就要用下面的方法调用
//fixed(float** fpp=farr)
//{
// return Test(fpp, row, col);
//}
}
}
}
// cmdll.c
// compile with: /LD
int __declspec(dllexport) SampleMethod(int i)
{
return i*10;
}
该示例使用两个文件 CM.cs 和 Cmdll.c 来说明 extern。C 文件是示例 2 中创建的外部 DLL,它从 C# 程序内调用。
// cm.cs
using System;
using System.Runtime.InteropServices;
public class MainClass
{
[DllImport("Cmdll.dll")]
public static extern int SampleMethod(int x);
static void Main()
{
Console.WriteLine("SampleMethod() returns {0}.", SampleMethod(5));
}
}
将该DLL文件复制到C#的BIN下面就可以了撒
回调函数我用过,
定义这个typedef void (*CALLBACKF) (char **, int, double, char **);
回调函数
using System.Runtime.InteropServices;
class API
{
[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
//上面这个可能不要 可能要,具体看你这个回调函数的调用方式是cdecl调用还是其他。
public delegate void ChCallback(参数自己一一对应);
[DllImport("Cmdll.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
public static extern bool FUN(char *, double , double , double ,ChCallback CallBack,int );
参数自己对应写,我的意思是自己定义一个delegate 对应C++ 中的CALLBACKF 然后再放到 fun参数里
}
然后其他类里实例api这个类后
pcallback = new API.ChCallback(MTEvent);
MTEvent为事件处理函数 意思就是typedef void (*CALLBACKF) (char **, int, double, char **);
这个在C#的具体回调实例!
public MTEvent(char **, int, double, char **)'
char 数组用 string接受
char *,这样定义
int len=128;
IntPtr cha = Marshal.AllocHGlobal(len);
len中间的len你自己看分配多少内存!cha 这就是一个指针。就是指向你分配的一块内存,然后把这个指针传递进去!
宇顷复方: 如果是托管C++的话可以像1L说的一样直接引用,不过估计这样你就不会问了吧…… C#当中可以调用Native代码DLL中导出的函数,前提是你知道这个函数的名字.不要以为这个条件很简单,这意味着你必须把这个函数定义为extern "C"(也...
龙亭区17321199304: C#如何调用C++编译的Dll? - ?
宇顷复方: 调用非托管的DLL文件需要 通过调用Windows API封装:LoadLibrary/FreeLibrary [DllImport("kernel32",EntryPoint="LoadLibrary",SetLastError=true)]static extern IntPtr LoadLibrary(string lpLibName); [DllImport("kernel32",...
龙亭区17321199304: 请问C#怎么调用C++的dll,把字节数组(字节数组byte[]作为形参)传入C++? - ?
宇顷复方: 我混混经验.在项目那里,可以引用 需要的 dll 文件,然后在程序中,using就行了,然后就可以调用这个dll中的函数了.C#中,可以定义一个byte数组,然后赋值,传入就行.
龙亭区17321199304: c#如何调用c++生成的dll文件 - ?
宇顷复方: /// <summary>/// 打开计算机串口/// </summary>/// <param name="handler">串口句柄指针</param>/// <param name="port">串口名</param>/// <returns>成功返回 0 ,失败返回非 0 值 </returns>[DllImport("DrfApiV10.dll")]public static extern int DrfCommOpen(ref IntPtr handler, string port);
龙亭区17321199304: c#使用DllImport调用c++dll的函数 - ?
宇顷复方: 调用格式如下:[DllImport("ex.dll", EntryPoint = "method")] public static extern void method(int a); 其中ex.dll为C++DLL名,method为函数名, 这里的int a为C++中方法的参数转换.例:C++DLL名:Interface.dll,函数为voidCopMemFree(...
龙亭区17321199304: C#调用C++编译出的DLL文件问题: - ?
宇顷复方: 首先,我先说,我不是太了解C#调用dll 但是我从C++做dll的经验来说,你在DLL工程中直接写的_declspec(dllexport),写死了.这个代表的是dll导出,在你要读取dll的时候应该会出问题.给个建议是,将_declspec(dllexport)改成一个宏,随便一...
龙亭区17321199304: C#怎样调用C++写的dll - ?
宇顷复方: public static extern bool Gnd_shuzu(String filename,float[] aa); 改成这样
龙亭区17321199304: c#如何调用c++生成的dll文件 - ?
宇顷复方: 创建新的动态链接库项目MyDLL打开MyDLL.h文件往其中添加以下代码:namespace Test{class MyMathClass{public:_declspec(dllexport) float Add(float,float);//加法};}函数实现添...
龙亭区17321199304: 怎么在vs2010中用c#调用c++的.dll文件 - ?
宇顷复方: 添加namespace using System.Runtime.InteropServices; 在调用dll的类里面添加[DllImport("dll文件名", EntryPoint = "接口函数名", CallingConvention = CallingConvention.StdCall)]public static extern 接口函数返回值 接口函数名(接口...
龙亭区17321199304: c# 调用c++生成的dll 返回数组 - ?
宇顷复方: 把函数写成API的形式,如函数定义为 void WINAPI aaa(BYTE*pBuf);,然后在def文件里添加一行aaa 在C#里这样声明:[DllImport("aaa.dll", EntryPoint = "aaa")] public static extern void aaa(byte[] pBuf);