因为一个项目的需要,在DLL的导出函数中使用了一个函数指针的参数,函数原型为:
public static int BusinessPackage(TMessage485[] pack485, int recCount,ref TMessage485[] returnPack485,int sendCount, int count)
定义的委托:
public delegate int dlBussPack485(TMessage485[] pack485, int recCount, ref TMessage485[] returnPack485, int sendCount, int count);
DLL引用声明为:
[DllImport(DLLName, CharSet = CharSet.Ansi)]
public static extern Boolean RunServer(int outTime, int sendTime, int port,[MarshalAs(UnmanagedType.FunctionPtr)] dlBussPack485 dealFunc);DLL为delphi7开发,原型为:
//启动服务
//outTime:接收数据超时 sendTime:处理数据超时
//port:开启服务端口  func 指定业务逻辑处理函数指针
//返回 True表示成功启动服务,False表示启动失败
function RunServer(outTime:integer;sendTime:integer;port:integer;func :TBusinessPackege):boolean;stdcall;
TBusinessPackege   = function(pack485:array of TMessage485;var returnPack485 :array of TMessage485;count :integer) : integer;
因为语言问题,两边的参数上不一致的。DELPHI中ARRAY传递的时候需要在后面指定一个长度,才能保证调用成功。
在这个的基础我另外申明另外一个函数:
function BusinessPackageT(pack485:array of TMessage485;var returnPack485 :array of TMessage485;count :integer):integer;stdcall;
此函数在C#中的申明为:
 public static extern int BusinessPackageT(TMessage485[] pack485,int recCount, ref TMessage485[] returnPack485,int sendCount, int count);
这个函数调用是正常的,参数和结果都很正确。上面那个传递的函数指针就不能运行了,一运行就会抱错,整个程序自动关闭。
托管调试助手“FatalExecutionEngineError”在“D:\我的文档\桌面\工位阅读器DEMO\RFIDSERVER\RFIDSERVER\bin\Debug\RFIDSERVER.exe”中检测到故障。
其他信息: 运行库遇到了错误。此错误的地址为 0x79e9e1b0,在线程 0xd54 上。错误代码为 0xc0000005。此错误可能是 CLR 中的 bug,或者是用户代码的不安全部分或不可验证部分中的 bug。此 bug 的常见来源包括用户对 COM-interop 或 PInvoke 的封送处理错误,这些错误可能会损坏堆栈。
本人功力不够,还请高手指点一二!

解决方案 »

  1.   

    补充一下:回调函数是在delphi开发的DLL中运行的,运行的具体地方是在一个TCP线程中!
    那个回调函数的作用是来做数据处理的。
    DELPHI调用原码,
    dynaFunc 为上面定义的:
    TBusinessPackege   = function(pack485:array of TMessage485;var returnPack485 :array of TMessage485;count :integer) : integer;
    调用原码
    function TServerThread.DynamicBusinessPackage(pack485:array of TMessage485;var returnPack485 :array of TMessage485;count :integer):integer;
    begin
      try
      begin
      if Assigned(dynaFunc) then
       result :=  dynaFunc(pack485, returnPack485,count)
      else result := 0;
      end
      except on E :Exception do
      begin
        result := e.HelpContext;
      end;
      end;
    end;昨天开始发现这个问题,还没有解决!实在是惭愧。
      

  2.   

    两边的参数进栈方式不一样。一种是StdCall,一种是PascalCall
      

  3.   

    谢谢L上的兄弟,已经能够回调了!不过参数传入的时候出了问题,第一数组只能接收一条数据,而且是错的,第二个数组就完全是NULL了,
    还请进一步指点,我这里也在找相关资料!谢谢。
      

  4.   

    自己顶下,请高手指点一下!要疯了。
        public delegate int dlBussPack485([MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Struct, SizeConst = 61)]TMessage485[] pack485, int reccount, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Struct, SizeConst = 61)] TMessage485[] returnPack485, int returnCount, int count);
    我把委托申明成这样后,可以调用,只有2个问题,1 returnPack485这个参数传入错误,也就是说里面的数据不对,2 这个参数需要按引用传递进来的,可是如果用REF调用后,是NULL的。 
      

  5.   

    我去DELPHI版再去开个,请各位出出注意了!
      

  6.   

    不好意思,这个帖子早就结了!最后的可用的委托原型定义为:/// <summary>
    /// 业务逻辑处理接收包,并返回
    /// </summary>
    /// <param name="pack485">接收的485包</param>
    /// <param name="recCount">接收的包数量</param>
    /// <param name="returnPack485">返回的包</param>
    /// <param name="returnCount">返回的包长度</param>
    /// <param name="count">有效的接收包数量</param>
    /// <returns>有效的返回包数量</returns>
    public  int BusinessPackage(TMessage485[] pack485, int recCount, [In, Out] TMessage485[] returnPack485, int returnCount, int count)