2021/1/9 踩的C语言回调函数一个坑

/******************************************
背景:第三方C语言写的一个库,没有头文件,也不知道接口。
只有一个C#demo。

C# 接口:
public delegate int EventHandler(int evt, string channel, string content);

[DllImport("pmon_lib.dll", EntryPoint = "PmonInit", CallingConvention = CallingConvention.StdCall)]
private static extern bool init(EventHandler e, int tracelevel, bool isAsync);

使用dumpbin工具也看不到函数形参:
Dump of file pmon_lib.dll

File Type: DLL

  Section contains the following exports for pmon_lib.dll

    00000000 characteristics
    4F8677B1 time date stamp Thu Apr 12 14:35:29 2012
        0.00 version
           1 ordinal base
          13 number of functions
          13 number of names

    ordinal hint RVA      name

          1    0 00013550 GetChannelPointer
          2    1 000134F0 GetChannelStatus
          3    2 00013500 GetChannelSubStatus
          4    3 000134B0 LockChannel
          5    4 00013520 PausePmonAcknowledge
          6    5 00013510 PauseUdpDriverResponse
          7    6 00013470 PmonInit
          8    7 000134C0 ReleaseChannel
          9    8 000134E0 RestartChannel
         10    9 00013490 SendData
         11    A 00013530 SendPmonMessage
         12    B 000135D0 SetChannelPointer
         13    C 000134D0 StopChannel

  Summary

        4000 .data
        7000 .rdata
        3000 .reloc
       27000 .text
******************************************/

//方法1(这个方法最后是失败的)
#include <iostream>
#include <string>
#include <Windows.h>
#include <functional>
using namespace std;

int EventCallback(int evt, string channel, string content)
{
    return 0;
}

#define BIND_CALLBACK_1(func)   std::bind(&func, placeholders::_1, placeholders::_2, placeholders::_3)
typedef std::function<int(int, string, string)> EventDelegate;

//动态加载
typedef bool(*PmonInit)(EventDelegate e, int tracelevel, bool isAsync);

int main()
{
    HINSTANCE hDll;
    hDll = LoadLibrary("pmon_lib.dll");
    if (hDll != NULL)
    {
        PmonInit init = (PmonInit)GetProcAddress(hDll, "PmonInit");
        bool ret = init(BIND_CALLBACK_1(EventCallback), 0, false);
    }
    return 0;
}

//方法2(这个方法最后是成功的)
#include <iostream>
#include <string>
#include <Windows.h>
#include <functional>
using namespace std;

typedef int(CALLBACK *fEventCallback)(int evt, char* channel, char* content);
typedef bool(*PmonInit)(fEventCallback cbEventCallback, int tracelevel, bool isAsync);

int CALLBACK g_fTestCallback(int evt, char* channel, char* content)
{
    return 0;
}

int main()
{
    HINSTANCE hDll;
    hDll = LoadLibrary("pmon_lib.dll");
    if (hDll != NULL)
    {
        PmonInit init = (PmonInit)GetProcAddress(hDll, "PmonInit");
        bool ret = init(g_fTestCallback, 0, false);
    }
    return 0;
}

/******************************************************/
/*
总结:
方法1也能调用函数成功,但有可能是没有注册回调函数成功,导致接口内部使用回调函数时导致程序崩溃。
......
现在还没有高明白为什么方法1不行。
有知道的小伙伴欢迎给我评论留言,3q
*/

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值