zoukankan      html  css  js  c++  java
  • C# 函数 传入 C++动态库中 做回调函数

    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();
                    }
                }
            }
           
        }
    }

     

  • 相关阅读:
    mysql启动时报错:Starting MySQL... ERROR! The server quit without updating PID file (/opt/mysql/data/mysql.pid)
    awk技巧【转】
    在分析nginx日志时常用命令总结【转】
    mybatis 详解(八)------ 懒加载
    mybatis 详解(七)------一对一、一对多、多对多
    mybatis 详解(六)------通过mapper接口加载映射文件
    mybatis 详解(五)------动态SQL
    mybatis 详解(四)------properties以及别名定义
    mybatis 详解(三)------入门实例(基于注解)
    mybatis 详解(二)------入门实例(基于XML)
  • 原文地址:https://www.cnblogs.com/pumax/p/1833205.html
Copyright © 2011-2022 走看看