zoukankan      html  css  js  c++  java
  • 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字节),这样才干得到正确的兴许数据地址.
  • 相关阅读:
    SpringCloud组件---Ribbon
    SpringCloud组件---Eureka
    tomcat及Jetty远程调试debug
    mysql 删除重复数据
    mysql执行SQL语句时报错:[Err] 3
    线程池原理剖析
    上限下限
    线程池Executors、Callable与Future的应用
    spring获取bean(自定义工具类)
    java.util.concurrent.Exchanger应用范例
  • 原文地址:https://www.cnblogs.com/wgwyanfs/p/6952873.html
Copyright © 2011-2022 走看看