• 64位程序调用32位DLL


            近期再把原来写的股票分析程序转换成64位版本号,程序中调用了银江的通视数据接口dll,由于银江提供的dll是32位的,但windows以下64位程序并不能直接调用32位的dll,所以仅仅能百度了.
            网上有说用进程外com的方式能够,之前从没接触过com,硬着头皮搞了半天,发现了问题,进程外com对于dll提供函数返回值不涉及指针的话没有不论什么问题,可是假设dll函数返回值是一个指针,问题就来了,因为这个指针和我自己的数据接收程序不在同一个进程地址空间,所以根本没有办法通过指针得到正确的接收数据.所以仅仅能放弃这种方法,转向怎样在进程间传递数据.
            我自己程序是用QT编写,mingw编译的,网上关于进程间通信(IPC)资料一大把,看了一下基本上QT在windows以下假设想在进程间传递大数据,仅仅能用LocalSocket或者共享内存的方式.两种方式的基本思路几乎相同,我自己的接收程序是64位的,另外在写一个32位的server程序,负责调用银江的数据接口dll,server程序接收到数据以后,以上面两种方式传递给我64位的接收程序就能够了. 
            首先以LocalSocket的方式来设计接口的,由于共享内存方式会设计比較麻烦的进程间同步问题,localsocket本身就有一条同步信号机制可供使用,详细涉及使用QT的QLocalSocket,QLocalServer类,网上资料非常多,不赘述.既然是首先提这样的方式,肯定是由于终于没选他,理由是,localsocket会把我传的整块数据随即切割,须要我在接收端推断并又一次合成原始完整块数据.这就要求接收端多余的推断操作,和内存创建销毁操作,终于还是放弃了.当然我并没有太深入的去学习localsocket这样的方式有没有办法不自己主动切割发送的完整大块数据,假设有的话,这应该是一种理想的方式.
            以下就要讲讲我终于採用的共享内存方式了,主要涉及QT的QSharedPointer类,开3个共享内存;
            第1个用来存储接收到的数据块.
            第2个用来放接收端(64位)的winid,主要是提供给发送32位的dll调用端读取,在接收到数据后通知64位的接收端有新的数据须要从共享内存中读取;
            第3个共享内存区是同步信号区,存了一个整型变量,1代表等待64位client读取数据,0代表没有须要client读取的数据.程序的初始状态这个值为0,32位server端接收到新数据后,会先进入一个轮询过程,在这个值为1时一直等待,仅仅有在这个值为0的时候才会打开数据共享区,并将数据放入共享区,之后再将这个值置为0.并发送给64位client通知消息(用windows的API,函数PostMessageW,里面目标窗体句柄就是第2个共享区中的数据);之后client收到消息以后,会先去读取共享内存中的数据,将起copy到本地进程中,然后置这里的信号量置为0.
            共享内存方式基本就如上所述了,当然中间还是会有点小问题,由于接收到银江数据头是以下这种结构:
            typedef struct tagRCV_DATA
    {
    int m_wDataType; // 文件类型
    int m_nPacketNum; // 记录数,參见注一
    RCV_FILE_HEADEx m_File; // 文件接口
    BOOL m_bDISK; // 文件是否已存盘的文件
    union
    {
    RCV_REPORT_STRUCTEx * m_pReport;
    RCV_HISTORY_STRUCTEx * m_pDay;
    RCV_MINUTE_STRUCTEx * m_pMinute;
    RCV_POWER_STRUCTEx * m_pPower;
    void * m_pData; // 參见注二
    };
    } RCV_DATA,*PRCV_DATA;
            能够看出最后一个是个指针,这个指针指实际上在32位server端指向的是这个数据头以下的紧接着的内存地址,可是这个地址是server进程中的绝对地址,到了64位client,假设仍然依照这个值,就不可能得到正确的数据,所以client不应该用这个值来对兴许的数据訪问,而是在copy下来已经在本进程内存中的数据包的首地址上加上RCV_DATA这个数据包头的大小(这里是288字节),这样才干得到正确的兴许数据地址.
  • 相关阅读:
    BZOJ2821 作诗(Poetize) 【分块】
    BZOJ2724 蒲公英 【分块】
    Codeforces 17E Palisection 【Manacher】
    BZOJ2565 最长双回文串 【Manacher】
    Codeforces 25E Test 【Hash】
    CODEVS3013 单词背诵 【Hash】【MAP】
    HDU2825 Wireless Password 【AC自动机】【状压DP】
    HDU2896 病毒侵袭 【AC自动机】
    HDU3065 病毒侵袭持续中【AC自动机】
    HDU2222 Keywords Search 【AC自动机】
  • 原文地址:https://www.cnblogs.com/wgwyanfs/p/6952873.html
Copyright © 2020-2023  润新知