zoukankan      html  css  js  c++  java
  • C# 调用C++ SDK/API的问题总结

    1.回调函数的使用

    c++的回调函数如下所示:

    typedef void (CALLBACK *Data)(long                lHandle,
    
                                        DATA_TYPE     eDataType,
    
                                        unsigned char       *pBuffer,
    
                                        unsigned long       lBufSize,
    
                                        void                *pUserData)
    

      

    调用回调函数的函数如下所示:

    SDK_API long STDCALL StartData(long             lID,
    
                                                S_DATA_INFO  *pDataInfo,
    
                                                 Data       fData,
    
                                                 Void             *pUserData = NULL)
    

    C#里对应的就是使用委托了。

    回调函数对应的委托声明:

    CallingConvention.StdCall还是很有用的。
    [UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
    public delegate void Data(int lHandle,
    DATA_TYPE eDataType,
    IntPtr pBuffer,
    uint lBufSize,
    IntPtr pUserData);
    

    调用委托的函数:

    [DllImport("SDK.dll")]
            public extern static int StartData(int lID,
                                                 ref DATA_INFO pDataInfo,
                                                 Data fRealData,
                                                 IntPtr pUserData);
    

     

    使用方法:

    首先声明一个全局变量myData,如果是函数里临时声明的变量可能在函数执行结束时就被垃圾回收了,后面的自然无法执行了。

    SDK.Data myData;

    使用时给它初始化

    myCBRealData = new IPCSDK.CBRealData(DoData);

    然后调用执行函数

    int lData = SDK.StartData(ID, ref dataInfo, myData, IntPtr.Zero);

    最后DoData函数里执行回调函数该做的事

    public void DoData(int lHandle, SDK.DATA_TYPE eDataType, IntPtr pBuffer, uint lBufSize, IntPtr pUserData)

    {

    ....

    }

    2.struct 结构体大小的设置

    C++很简单,数组可以直接定义长度

    typedef struct tagInfo

    {

             unsigned char ucSoftWareVersion[4];//软件版本

    }S_INFO;

    C#:

    要使用[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]

    public struct S_INFO
    {
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
    public byte[] ucSoftWareVersion;//软件版本

    };

    3.const char * 等这一类的转换

    char * 一般直接用string就好了,

    const char *一般要 StringBuilder

    出现错误就多试试了

    其他信息: 对 PInvoke 函数“SDK::Open”的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。

    这个错误网上不少说是要在函数上面加CallingConvention.StdCall

    [DllImport("SDK.dll",  CallingConvention= CallingConvention.StdCall, CharSet= CharSet.Ansi)]

    试了没用,最后发现是const char *要 StringBuilder,用string、intptr都没用

    4.C++的long一般是4个字节对应C#的int

    5.指针类型一般用intptr,然后再读出来

    6.其他类型实在不清楚就查一下,各种转换文章很多,当然不一定全对,要多尝试

  • 相关阅读:
    Yocto开发笔记之《驱动调试-华为3G模块》(QQ交流群:519230208)
    Yocto开发笔记之《应用程序架构》(QQ交流群:519230208)
    Yocto开发笔记之《串口驱动调试》(QQ交流群:519230208)
    Yocto开发笔记之《快速入门,环境搭建 & 编译》(QQ交流群:519230208)
    Linux Canbus调试笔记
    ubuntu默认防火墙
    Linux安全之——Ubuntu的iptable命令使用
    嵌入式Linux系统开发环境搭建
    在Android上实现使用Facebook登录(基于Facebook SDK 3.5)
    Android应用内语言切换实现(转)
  • 原文地址:https://www.cnblogs.com/jhlong/p/5714937.html
Copyright © 2011-2022 走看看