问题1:
typedef struct tagRCV_FILE_HEADEx
{
DWORD m_dwAttrib;
DWORD m_dwLen;
union 
{
DWORD m_dwSerialNo;
time_t m_FileTime;
};
char m_szFileName[MAX_PATH];
} RCV_FILE_HEADEx,*PRCV_FILE_HEADEx;注意,关键处在:union,
如果union在记录定义内部,使用case integer of就可以了,但是,这个C++定义跑到了外
面,如何对应转换呢?
背景:
我在实现一个读取股票接口卡的小软件,但是股票卡的动态联结库Stock.dll是c++写的,提供的输出函数,结构定义如上,只输出地址指针,
我用Delphi无法定义上述等价结构,就提取不出数据,因此,请各位给个建议,或者解决办法。我目前想到了一个替代办法,加入上面的语言问题解决不了,我就计划用Visual C++重新写个StockDelphi.dll,来作为我的Delphi软件和Stock.dll的转接桥梁。StockDelphi把数据包装,然后以Xml文件格式传递出来。这个办法显然有点绕,我以前一直认为Delphi和C++没有什么区别,所谓优点各自有,但是不存在不可调和的矛盾。
目前,真正的遇到了。
这个语言细节确实影响到了我的实现。
请各位给个建议。
谢谢!
问题2:
如下的一对一转换是不存在的,
typedef struct tagRCV_FILE_HEADEx
{
        DWORD   m_dwAttrib;
        DWORD   m_dwLen;
        union
        {
                DWORD   m_dwSerialNo;
                time_t  m_FileTime;
        };
        char    m_szFileName[MAX_PATH];
} RCV_FILE_HEADEx,*PRCV_FILE_HEADEx;因为在C++定义里,union可以在各个变量中间,但是,在Delphi内部好像不可以
我的定义如下:Delphi报告非法
tagRCV_FILE_HEADEx=Record
        m_dwAttrib:DWORD;
        m_dwLen:DWORD;
        case Integer of
                0:(m_dwSerialNo:DWORD);
                1:(m_FileTime:TDateTime);
  m_szFileName:array[0..MAX_PATH-1]of char;
end;如果把case 部分写在m_szFileName之后,则没问题。
如此看来,这是不可调和的矛盾。
我之所以在意这个次序,是因为他们虽然占用同样大小的内存,但是在内存空间分配截然不
同,我就无法用这个Delphi结构来正确的读取C++程序用它自己结构写在硬盘上的数据
what can i do?and how?

解决方案 »

  1.   

    >>union可以在各个变量中间,但是,在Delphi内部好像不可以做多個中間聲明出來, 如何?type
     TmyRec = record
               case Integer of
                    0:(m_dwSerialNo:DWORD);
                    1:(m_FileTime:TDateTime);
     end;tagRCV_FILE_HEADEx=Record
            m_dwAttrib:DWORD;
            m_dwLen:DWORD;
            myrec: TmyRec;
      m_szFileName:array[0..MAX_PATH-1]of char;
    end;
      

  2.   

    嗯。。DELPHI中一般做法是再申明出一个结构
      

  3.   

    谢谢你!眼睛同志,但是这样定义一来,其在内存里的结构就发生了变化,就是说,我从C++ DLL内部提取不出等价数据了。
      

  4.   

    或许也可以试试这样。tagRCV_FILE_HEADEx=Record
            m_dwAttrib:DWORD;
            m_dwLen:DWORD;
            case Integer of
                    0:(m_dwSerialNo:DWORD);
                    1:(m_FileTime:TDateTime;
      m_szFileName:array[0..MAX_PATH-1]of char);
    end;
      

  5.   

    你好,cnhgj(戏子) (作为一名艺人) 
    “DELPHI中一般做法是再申明出一个结构”
    必须与C++结构完全等价,因为数据流是C++用自己的结构写到buffer里的,我们要想还原,必须结构完全一致,才能读取到等价的数据块。
      

  6.   

    我们来举个例。。好像MIXERCONTROLDETAILS这个结构C声明是typedef struct { 
        DWORD cbStruct; 
        DWORD dwControlID; 
        DWORD cChannels; 
        union { 
            HWND  hwndOwner; 
            DWORD cMultipleItems; 
        }; 
        DWORD  cbDetails; 
        LPVOID paDetails; 
    } MIXERCONTROLDETAILS; 
     
    Delphi声明是tMIXERCONTROLDETAILS = record
        cbStruct: DWORD;       { size in bytes of MIXERCONTROLDETAILS }
        dwControlID: DWORD;    { control id to get/set details on }
        cChannels: DWORD;      { number of channels in paDetails array }
        case Integer of
       0: (hwndOwner: HWND);        { for MIXER_SETCONTROLDETAILSF_CUSTOM }
       1: (cMultipleItems: DWORD;   { if _MULTIPLE, the number of items per channel }
           cbDetails: DWORD;        { size of _one_ details_XX struct }
           paDetails: Pointer);     { pointer to array of details_XX structs }
      end;
      

  7.   

    谢谢你,艺人。
    非常感谢您的真实代码片段。
    我想具体问一下,您这个片段的背景,C++用MIXERCONTROLDETAILS写入到磁盘的数据,Delphi可以用您写的这个结构正确的读取出来吗?如果能帮我解决这个问题,我可以开贴再给分。谢谢!!!
      

  8.   

    WORD m_cbSize; // 结构大小
    time_t m_time;    // 交易时间
    WORD m_wMarket;
    另外,请问艺人,c中的time_t 是什么数据类型?可以用Delphi的什么类型来对应?TDateTime?就是实数类型?
      

  9.   

    time_t long integer Represents time values in mktime and time. TIME.H
      

  10.   

    >>其在内存里的结构就发生了变化
    我覺得應該不會, 如果不同, 不是這樣原因造成的如:
    tagRCV_FILE_HEADEx=Record
            m_dwAttrib:DWORD;
            m_dwLen:DWORD;
    end;應該與TmyRec = record
             m_dwAttrib:DWORD;
            m_dwLen:DWORD;
    end;tagRCV_FILE_HEADEx=Record
      myRec: TmyRec;
    end;
    是一樣的
      

  11.   

    如果同样的结构C与delphi存的方式一不样,其实这没办法解决,我认为
      

  12.   

    void *对应的是Pointer,可以吗?
    就是内存指针。
    如下两个结构虽然一样,但是,无法一次性读取出来,比如,DLL提供了一个指针,就是void * buf,但是无法一次性完整读取进行转。
    如:
    tagRCV_FILE_HEADEx=Record
            m_dwAttrib:DWORD;
            m_dwLen:DWORD;
    end;應該與TmyRec = record
             m_dwAttrib:DWORD;
            m_dwLen:DWORD;
    end;tagRCV_FILE_HEADEx=Record
      myRec: TmyRec;
    end;
    是一樣的
      

  13.   

    typedef long time_t; // 4 bytes.TDateTime = type Double; // 8 bytes. 应该不行吧。。void *对应的是Pointer,可以吗?// OK.void * buf一般对void*类型的内存块必须还要传入读取的长度
      

  14.   

    谢谢大龙:)
    我已经把time类型全部换成了Delphi的longint了,不过,还是有错。
    看来我只能写个C++ DLL来做转换了:)
    谢谢各位。
    如果各位还有什么高见,敬请帮忙!
      

  15.   

    各位!!!
    好像可以了!暂时调试通过,我再继续试验。
    非常感谢艺人贴出的真实代码片段,及大龙的提醒。
    好像问题的关键就在于time的字节。如果成功了,我一定写个转换经验放在这里,消除我对Delphi的偏见。也供大家参看。
    谢谢二位及其他跟帖帮忙的兄弟!!!
    我先调试去了:)
      

  16.   

    呵呵 delphi 还是很强悍的...虽然我也更喜欢VC.
      

  17.   

    如果问题顺利解决,分大家都有份:)
    我还有好几千分,再给几百出去没问题。这些都是身外之物:)
    另外,C++里的float类型多少个字节?用Delphi的real对应是否一致?
      

  18.   

    C++:
    float 4 bytes delphi:
    real: 8 bytes;Type Range Significant digits Size in bytes
    Real 5.0 x 10^-324 .. 1.7 x 10^308 15-16 8
    Double 5.0 x 10^-324 .. 1.7 x 10^308 15-16 8
      

  19.   

    谢谢大龙,看来这个问题,是解决不了了,必须得单独写一个DLL来转换了。
    目前的问题好像就出在float类型上。我用Delphi的Single(4bytes)来替代float,数据读取出来的仍然不对。
    以后有时间再继续探索了。我暂时先用VC写个DLL转换一下。
    时间紧迫,现解决完问题再说,以后再探讨了。
    :)
    仍然会欢迎各位继续跟帖,给与帮助:)
      

  20.   


    const MAX_PATH=....;
    typeTRCV_FILE_HEADEx=packed record
      m_dwAttrib  :Cardinal;
      m_dwLen     :Cardinal;
      SerialNo_or_time: Cardinal;//呵呵.何必麻烦,反正都是四字节
      m_szFileName  :array[0..MAX_PATH-1]of char;
    end;
    再弄一个C语言的time_t与DELPHI TDATETIME的转换函数,也不是难事..
    也不用麻烦写,在GOOGLE一搜.COPY在下面..
    //-------------------------------------------------------------
    如果是标准c函数time()返回的时间 time_t 类型(就是DWORD)
    它是距离 1970-1-1 之后的秒数,这样计算为TDateTime
    假设你的DWORD时间是 t
    那么这样转成TDateTime: 
       EncodeDate(1970,1,1)+ t/24.0/60.0/60.0
      

  21.   

    谢谢 halfdream(哈欠)!
    我正在做这个时间转换,刚好看到你的帖子了:)非常感谢!
      

  22.   

    各位兄弟好!问题基本解决了,还是用Delphi直接读取的,非常感谢各位跟帖的兄弟和热心帮忙着,特别感谢大龙和艺人还有halfdream(哈欠) ,
    言出即行,
    你们三人分别90分60分和30分,余下20分给其他跟贴的兄弟。非常感谢!
    已经可以完整的读取股票行情数据了:)