labview 读取zigbee数据采集模块的数据,打包成dll我用delphi调用,报内存冲突。access violation at 0x300053e0:read of address 0x00000000'
但是用VC调用同样的DLL却没有问题。请问是为什么?
程序如下:(动态调用dll)
privatepublicend;
type td1=record
          elt1:double;
          elt2:double;
          elt3:double;
          elt4:double;
         end;
     PTD1=TD1;
  Tzigbee1=procedure(zigbee:PTD1);stdcall;implementation
  procedure DAQ1;external 'SharedLib.dll';procedure Tform1.button1click(sender:tobject);
var midWare:TD1;
    dllhandle:thandle;
    pro:Tzigbee1;
begin
  dllhandle:LoadLibrary('SharedLib.dll');
  try
   @pro:=getprocAddress(DllHandle,'zigbee1');
   if assigned(@pro) then
   begin
     pro(midWare);
     memo1.lines.add(floattostr(midware.elt1))
   end;
   finally
      freeLibrary(dllhandle);
end;
end;
我单步调试,程序运行到最后一句都没有错,再执行 就报刚刚的内存突冲。哪位高手给解答一下嘛,急死了。
我把我所有的分都拿出来了,如果解决了,我去挣分再给您补多一些。不胜感激;

解决方案 »

  1.   

    把 implementation下面那句去了,也是同样的错误。那句是写错了的。
      

  2.   

    就是这样动态调用dll的,没啥问题不过参数是不是record类型? 如果是的话应该用var
    如果是指针类型的record,就要先申请内存
      

  3.   

    试一下增加多次读,看出错不
        begin
         pro(midWare);
         memo1.lines.add(floattostr(midware.elt1))
         pro(midWare);
         memo1.lines.add(floattostr(midware.elt1))
         pro(midWare);
         memo1.lines.add(floattostr(midware.elt1))
       end;
     
      

  4.   

    我没有看到你DLL中的写法,有些问题还不是很确定
    但你这里有几个错误,需要注意
    1:
    implementation
      procedure DAQ1;external 'SharedLib.dll';这句话的意思是,静态加载DLL,引用输出函数‘DAQ1’,所谓静态加载,指的是在程序启动的时候,就自动加载DLL,在程序结束的时候自动卸载DLL,在寻找DLL的时候大致按照以下路径去搜寻:程序启动路径(程序启动路径可能和程序所在路径不同),系统的环境变量PATH中定义的各个路径(着其中包括SYSTEM32,Windows,program and files,等,一些系统路径在64bit系统下会被自动重定向)。如果你的DLL输出函数名称不等于你声明的函数名 需要用name指示字来指定你搜需的DLL输出函数。如果你的DLL是使用C来编写的,需要指示字cdecl来指定调用参数的顺序。同一个动态链接库,只能被一个进程加载一次。所以如果你已经静态加载了DLL,就不要再显示卸载该DLL,否则会在程序退出时报错,也就是说 freeLibrary(dllhandle); 这句话不要调用。但dllhandle:=LoadLibrary('SharedLib.dll');这句话调用不会出错,因为该函数实现中会先寻找有没有加载该DLL的句柄,如果已经加载,就立即返回句柄,不会重复加载。2:
    DLL中如果你需要传递结构体的话,你在DELPHI中应该声明结构体指针,而不是直接使用结构体变量。
    我不清楚你DLL中如何处理结构体参数的,但一般C在处理结构体的时候会有以下惯例,使用结构体指针,在函数内部初始化结构体,并赋值,返回结构体的内存大小,另外再提供释放结构体的函数,供使用完值后释放内存。或者,由外部传入一个已经初始化好的结构体,传入结构体的大小,函数内部只负责赋值,由外部负责结构体的释放。对于DELPHI中,如果在函数中声明了一个结构体变量,而非结构体指针,这种情况下,编译器会自动为结构体初始化内存,在函数退出时自动释放结构体,无需手动管理。这种机制,也可能会引起楼主提到的异常。我没有看到楼主完整的代码,以上只是我的猜想。
    总结起来是:
    如果传递结构体,请使用指针,并注意内存管理。
    如果DLL是C实现的,请在声明函数类型的时候使用指示字cdecl
    如果是静态加载的,则不需要显示释放DLL
      

  5.   


    今天去和一高手请教了下,最后把问题解决了,我们解决问题的过程和你讲的很多很相近,
    最后我们在Labview里重新生成DLL,直接返回值,没有用结构体来传递值,最后调用成功。所以我们怀疑是他们生成的Dll的问题,因为要与硬件进行数据交互。但是我还是感谢您的回答。分全给您吧!因为你讲的这些,正是我昨天没有搞明白的,最近用delphi都是边学边用,所以有好多问题搞的一知半解的。