C#如何調用C++類封裝的DLL

longshui38 2017-07-22 12:13:29
C++封装的DLL:

有C++实体类A,给A添加一个纯虚的父类IA,再写一个函数返回IA的指针,并且让这个指针指向实体类A,返回IA指针的这个函数F作为DLL的导出函数。--用以上方法实现了类A的DLL封装。

C#:

导入这个DLL,需要使用这个F获取C++类的指针,F有一个形参是函数指针,F的形式类似于:

IA* F(double (*Proc)(double* b,double* x,void* t))。

请问C#如何正确使用这个函数获取C++类的指针,并传递一个函数指针的形参?
...全文
434 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
XBodhi. 2017-08-01
  • 打赏
  • 举报
回复
引用 10 楼 longshui38 的回复:
[quote=引用 9 楼 pc0de 的回复:] [quote=引用 6 楼 longshui38 的回复:] 非常感謝andwp,現在C#可以使用C++虛類中的方法了。可是在傳遞函數指針的時候出錯了: IA* F(double (*Proc)(double* b,double* x,void* t))中的函數指針也是從別的C++ dll中導入的。 先在C#中聲明委託delegate double ProcCallback(double[] b, double []x, Intptr t); 然後從另外一個dll中導入: [DllImport("dllname1",EntryPoint=OnProc)] public static extern double OnProc((double[] b, double []x, Intptr t); 從別的dll中導入調用函數指針的那個函數 [DllImport("dllname2",,EntryPoint=F)] public static extern IntPtr F(ProcCallback pCallback); 2個dll和C#生成的exe都放在C#工程bin的debug下,我斷點跟蹤函數指針,確實傳給了dllname2中的C++代碼,但是在dllname2中的C++代碼調用傳進來的這個函數指針時就出錯了,實在搞不不明白。
没看懂您的意思呢。你是要把一个C的dll中指针导出赋值给另一个c?? 感觉不对呀,C#中申明的互操作调用,能直接当指针赋值吗 ?? 你试试从dll1获取到那个函数指针,然后传入到dll2?[/quote] dll1中導入的函数: [DllImport("dllname1",EntryPoint=OnProc)] public static extern double OnProc((double[] b, double []x, Intptr t); dll2中導入的函數,其中有一个形参是dll1中导入的函数的函数指针,先在C#中聲明委託delegate double ProcCallback(double[] b, double []x, Intptr t),然后让委托指向这个函数ProcCallback privateCallback = new ProcCallback(OnProc); [DllImport("dllname2",,EntryPoint=F)] public static extern IntPtr F(ProcCallback pCallback); IntPtr pIA = F(privateCallback );这样,通过dll2中类的构造函数将dll1中导入的函数指针,传给了dll2。但是在dll2内部使用这个函数指针的时候就会报那个错。[/quote] 参看 DllImport 属性
longshui38 2017-08-01
  • 打赏
  • 举报
回复
引用 9 楼 pc0de 的回复:
[quote=引用 6 楼 longshui38 的回复:] 非常感謝andwp,現在C#可以使用C++虛類中的方法了。可是在傳遞函數指針的時候出錯了: IA* F(double (*Proc)(double* b,double* x,void* t))中的函數指針也是從別的C++ dll中導入的。 先在C#中聲明委託delegate double ProcCallback(double[] b, double []x, Intptr t); 然後從另外一個dll中導入: [DllImport("dllname1",EntryPoint=OnProc)] public static extern double OnProc((double[] b, double []x, Intptr t); 從別的dll中導入調用函數指針的那個函數 [DllImport("dllname2",,EntryPoint=F)] public static extern IntPtr F(ProcCallback pCallback); 2個dll和C#生成的exe都放在C#工程bin的debug下,我斷點跟蹤函數指針,確實傳給了dllname2中的C++代碼,但是在dllname2中的C++代碼調用傳進來的這個函數指針時就出錯了,實在搞不不明白。
没看懂您的意思呢。你是要把一个C的dll中指针导出赋值给另一个c?? 感觉不对呀,C#中申明的互操作调用,能直接当指针赋值吗 ?? 你试试从dll1获取到那个函数指针,然后传入到dll2?[/quote] dll1中導入的函数: [DllImport("dllname1",EntryPoint=OnProc)] public static extern double OnProc((double[] b, double []x, Intptr t); dll2中導入的函數,其中有一个形参是dll1中导入的函数的函数指针,先在C#中聲明委託delegate double ProcCallback(double[] b, double []x, Intptr t),然后让委托指向这个函数ProcCallback privateCallback = new ProcCallback(OnProc); [DllImport("dllname2",,EntryPoint=F)] public static extern IntPtr F(ProcCallback pCallback); IntPtr pIA = F(privateCallback );这样,通过dll2中类的构造函数将dll1中导入的函数指针,传给了dll2。但是在dll2内部使用这个函数指针的时候就会报那个错。
longshui38 2017-08-01
  • 打赏
  • 举报
回复
引用
参看 DllImport 属性
我用的這個CallingConvention = CallingConvention.Cdecl,應該用哪個呢?
pc0de 2017-07-30
  • 打赏
  • 举报
回复
引用 6 楼 longshui38 的回复:
非常感謝andwp,現在C#可以使用C++虛類中的方法了。可是在傳遞函數指針的時候出錯了: IA* F(double (*Proc)(double* b,double* x,void* t))中的函數指針也是從別的C++ dll中導入的。 先在C#中聲明委託delegate double ProcCallback(double[] b, double []x, Intptr t); 然後從另外一個dll中導入: [DllImport("dllname1",EntryPoint=OnProc)] public static extern double OnProc((double[] b, double []x, Intptr t); 從別的dll中導入調用函數指針的那個函數 [DllImport("dllname2",,EntryPoint=F)] public static extern IntPtr F(ProcCallback pCallback); 2個dll和C#生成的exe都放在C#工程bin的debug下,我斷點跟蹤函數指針,確實傳給了dllname2中的C++代碼,但是在dllname2中的C++代碼調用傳進來的這個函數指針時就出錯了,實在搞不不明白。
没看懂您的意思呢。你是要把一个C的dll中指针导出赋值给另一个c?? 感觉不对呀,C#中申明的互操作调用,能直接当指针赋值吗 ?? 你试试从dll1获取到那个函数指针,然后传入到dll2?
yuhaoloen 2017-07-29
  • 打赏
  • 举报
回复
这个问题我在我的资源里上传了 一个例子你可以参看一下
longshui38 2017-07-29
  • 打赏
  • 举报
回复
引用 5 楼 pc0de 的回复:
[quote=引用 3 楼 longshui38 的回复:] [quote=引用 1 楼 pc0de 的回复:] C#可申明代理
delete double ProcCallback(double[] b, double []x, Intptr t); // 如果lz说的double* 与double*x 是数组的话。
double  OnProc((double[] b, double []x, Intptr t)
{
// todo 实现回调的方法
}

// 申明互操作方法
[DllImport("dllname")]
 static extern IntPtr F(ProcCallback pCallback);// 
调用方法

ProcCallback privateCallback = new ProcCallback(OnProc);
 IntPtr pIA = F(privateCallback);   
按照您說的方法編譯產生一個錯誤,委託類型的可訪問性要低於獲取類指針的函數。 還有一個問題:在C#中我獲取類的指針是intptr類型的,他怎麼知道C++中純虛類中有些什麼方法呢?我怎麼調用純虛類中的方法呢?[/quote] 1、访问性你可以设置成public 2、C++非托管导出到C#调用仿佛不能直接导出类,你得使用方法一个一个地封装。传回指针, 比如IA中有个void Func(void)方法,那么就得创建一个导出函数, 函数申明类似 void A_Func(IA* p); 然后在C#申明A_Func的互操作方法 void A_Func(Intptr p); 如果非要使用对象类型的封装,请使用COMhttps://msdn.microsoft.com/zh-cn/library/2x07fbw8(v=vs.100).aspx 官方文档,多看看不会错[/quote] 還有個函數指針傳遞的問題,能幫助解決一下嗎?
longshui38 2017-07-27
  • 打赏
  • 举报
回复
非常感謝andwp,現在C#可以使用C++虛類中的方法了。可是在傳遞函數指針的時候出錯了:


IA* F(double (*Proc)(double* b,double* x,void* t))中的函數指針也是從別的C++ dll中導入的。
先在C#中聲明委託delegate double ProcCallback(double[] b, double []x, Intptr t);
然後從另外一個dll中導入:
[DllImport("dllname1",EntryPoint=OnProc)]
public static extern double OnProc((double[] b, double []x, Intptr t);
從別的dll中導入調用函數指針的那個函數
[DllImport("dllname2",,EntryPoint=F)]
public static extern IntPtr F(ProcCallback pCallback);
2個dll和C#生成的exe都放在C#工程bin的debug下,我斷點跟蹤函數指針,確實傳給了dllname2中的C++代碼,但是在dllname2中的C++代碼調用傳進來的這個函數指針時就出錯了,實在搞不不明白。
pc0de 2017-07-24
  • 打赏
  • 举报
回复
引用 3 楼 longshui38 的回复:
[quote=引用 1 楼 pc0de 的回复:] C#可申明代理
delete double ProcCallback(double[] b, double []x, Intptr t); // 如果lz说的double* 与double*x 是数组的话。
double  OnProc((double[] b, double []x, Intptr t)
{
// todo 实现回调的方法
}

// 申明互操作方法
[DllImport("dllname")]
 static extern IntPtr F(ProcCallback pCallback);// 
调用方法

ProcCallback privateCallback = new ProcCallback(OnProc);
 IntPtr pIA = F(privateCallback);   
按照您說的方法編譯產生一個錯誤,委託類型的可訪問性要低於獲取類指針的函數。 還有一個問題:在C#中我獲取類的指針是intptr類型的,他怎麼知道C++中純虛類中有些什麼方法呢?我怎麼調用純虛類中的方法呢?[/quote] 1、访问性你可以设置成public 2、C++非托管导出到C#调用仿佛不能直接导出类,你得使用方法一个一个地封装。传回指针, 比如IA中有个void Func(void)方法,那么就得创建一个导出函数, 函数申明类似 void A_Func(IA* p); 然后在C#申明A_Func的互操作方法 void A_Func(Intptr p); 如果非要使用对象类型的封装,请使用COMhttps://msdn.microsoft.com/zh-cn/library/2x07fbw8(v=vs.100).aspx 官方文档,多看看不会错
pc0de 2017-07-24
  • 打赏
  • 举报
回复
引用 2 楼 caozhy 的回复:
是delegate(委托),不是delete、代理
谢谢更正
longshui38 2017-07-24
  • 打赏
  • 举报
回复
引用 1 楼 pc0de 的回复:
C#可申明代理
delete double ProcCallback(double[] b, double []x, Intptr t); // 如果lz说的double* 与double*x 是数组的话。
double OnProc((double[] b, double []x, Intptr t)
{
// todo 实现回调的方法
}



// 申明互操作方法
[DllImport("dllname")]
static extern IntPtr F(ProcCallback pCallback);//


调用方法

ProcCallback privateCallback = new ProcCallback(OnProc);
IntPtr pIA = F(privateCallback);



按照您說的方法編譯產生一個錯誤,委託類型的可訪問性要低於獲取類指針的函數。
還有一個問題:在C#中我獲取類的指針是intptr類型的,他怎麼知道C++中純虛類中有些什麼方法呢?我怎麼調用純虛類中的方法呢?
threenewbee 2017-07-23
  • 打赏
  • 举报
回复
是delegate(委托),不是delete、代理
pc0de 2017-07-23
  • 打赏
  • 举报
回复
C#可申明代理
delete double ProcCallback(double[] b, double []x, Intptr t); // 如果lz说的double* 与double*x 是数组的话。
double  OnProc((double[] b, double []x, Intptr t)
{
// todo 实现回调的方法
}

// 申明互操作方法
[DllImport("dllname")]
 static extern IntPtr F(ProcCallback pCallback);// 
调用方法

ProcCallback privateCallback = new ProcCallback(OnProc);
 IntPtr pIA = F(privateCallback);   

110,501

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧