C# 函数 传入 C++动态库中 做回调函数

时间:2022-01-09 19:00:09

 

 

MFC中调用C#写的DLL,   涵数接口为char*   proc(char*   a,char*   b);  
我用显式调用,定义   typedef   char*   (MYPROC)(char*   aa,char*   bb;每次调用后总会出现  

Run-Time     Check   Failure   #0—The   value   of   ESP   was   not   properly   saved  
across   a   function   call.   This   is   usually   a   result   of   calling   a   function  
declared   with   one   calling   convention   with   a   function   pointer   declared  
with   a   different   calling   convention.  

有什么解决办法  

 

现在定义   typedef   char*   (_stdcall   MYPROC)(char*   aa,char*   bb)后上边问题解决,不过传递参数的格式好象有点问题,MFC的char*     与c#的char*有什么不同吗?

 

 

<DllTest.h>

// 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
// DLLTEST_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
// 符号视为是被导出的。
#ifdef DLLTEST_EXPORTS
#define DLLTEST_API __declspec(dllexport)
#else
#define DLLTEST_API __declspec(dllimport)
#endif


typedef float (_stdcall Kin)(float , BYTE* ,  float  );

Kin *kin=0;

extern "C"
{
 DLLTEST_API int ndlltest;

 DLLTEST_API int fndlltest(void);

 DLLTEST_API float  kinescope(Kin kines) ;
   
 DLLTEST_API void   kinescope1(void(*   kines)(float   x,   float   y) ) ;
 


 DLLTEST_API int SetCallBack(Kin kines);
 DLLTEST_API float TestCallBack(float a,BYTE* pData,float b);

}

 

 

 

// dlltest.cpp : 定义 DLL 应用程序的导出函数。
//

#include "stdafx.h"
#include "dlltest.h"


// 这是导出变量的一个示例
extern DLLTEST_API int ndlltest=0;

// 这是导出函数的一个示例。
DLLTEST_API int fndlltest(void)
{
 return 42;
}


DLLTEST_API float   kinescope(Kin kines)
{
    float a,b;
 a=1.0;b=100.0;
     return a+b;
}


DLLTEST_API void   kinescope1(void(*   kines)(float   x,   float   y) )
{
 kines(10,20);
}

DLLTEST_API int SetCallBack(Kin kines)
{
 kin=&kines;
 return (int)kin;
}

DLLTEST_API float TestCallBack(float a,BYTE* pdata,float b)
{
 float val=0;
 if(kin)
 {
  val=(*kin)(a,pdata,b);
 }
 return val;
}

 

 

 

C#中调用代码


 

 

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace dlltestfrm
{
    public partial class Form1 : Form
    {

 

        public Form1()
        {
            InitializeComponent();
        }


        //----------------C#中调用代码---------------  

 


        [DllImport(@"C:\Users\puma\Documents\Visual Studio 2008\Projects\dlltest\Debug\dlltest.dll", CharSet = CharSet.Ansi, BestFitMapping = true)]
        static extern int SetCallBack(IntPtr pKines);
        [DllImport(@"C:\Users\puma\Documents\Visual Studio 2008\Projects\dlltest\Debug\dlltest.dll", CharSet = CharSet.Ansi, BestFitMapping = true)]
        unsafe static extern float TestCallBack(float a,byte* pdata,float b);

        //------------委托声明-------------
        unsafe public delegate float kinds(float x,byte* pdata ,float y);

        public static byte[] pBuf = new byte[10];
        public static int BufLen = 0;
        //---------------委托定义-------------------
        unsafe public   static   float   kds(float   x, byte* pdata,  float   y)
        {
            int i,j,len = (int)y;
            for (i = 0,j=0; i < len; i++)
            {
                j +=(int) pdata[i];
            }
            return (float)(x+j);
        }


        kinds kk;
        IntPtr pKinds;
        private void Form1_Load(object sender, EventArgs e)
        {

            //------------------调用---------------
            unsafe
            {
                kk = new kinds(kds);
                pKinds = Marshal.GetFunctionPointerForDelegate(kk);
                int pt = SetCallBack(pKinds);
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            byte[] pd = { 1, 2, 3, 4 };
            unsafe
            {
                fixed (byte* pp = pd)
                {
                    label1.Text = TestCallBack(float.Parse(textBox1.Text), pp, 4.0f).ToString();
                }
            }
        }
       
    }
}