3

我有一个包含 ADOConnection 和 ADOQuery 的 dll(Delphi),但是当在 java 中运行被调用的 DLL(使用 JNA)时,控制台会出现一些错误信息(如下):

Java 运行时环境检测到一个致命错误:

内部错误 (0xedfade),pid=4400,tid=3840

JRE 版本:6.0_25-b06 Java VM:Java HotSpot(TM) 客户端 VM(20.0-b11 混合模式,共享 windows-x86) 有问题的框架:C [KERNELBASE.dll+0x812f]

包含更多信息的错误报告文件保存为:C:\Users\Mmn1\Documents\NetBeansProjects\FLMOPDL\hs_err_pid4400.log

如果您想提交错误报告,请访问:http:
//java.sun.com/webapps/bugreport/crash.jsp 崩溃发生在 Java 虚拟机之外的本地代码中。请参阅有问题的框架以了解报告错误的位置。

这是什么bug?(我意识到只有在 ADOConnection ADOQuery 的情况下我有一个表单或作为一个组件并且如果我删除这些组件并执行一个简单的功能,它才会正常工作)。

编辑:

类似的例子如下:

library TESTLIB;
{$DEFINE TESTLIB}

uses
  System.SysUtils,
  System.Classes,
  TestInt in 'TestInt.pas',
  Vcl.Dialogs,
  sharemem,
  Data.DB, Data.Win.ADODB;

{$R *.res}

function MyReturn(x: Integer; Test: PTest): Boolean; stdcall;
var
  ado: TADOQuery;
begin
    Result := True;
    //ado := TADOQuery.Create(nil); <- With this i got a error!
end;

exports MyReturn;

begin
end.

Java中的接口

public interface TestInt extends StdCallLibrary {
    TestInt INSTANCE = (TestInt)Native.loadLibrary("C:/test/Win32/Debug/TESTLIB", TestInt.class);

    class Test extends Structure {
        public String vResult;

        public Test() { }
        public Test(int x, Pointer p) {
            super(p);
            read();
        }
        protected List getFieldOrder() { return Arrays.asList(new String[] { "vResult" }); }
    }

    Boolean MyReturn(int x, Test test);
}

结论:当我使用组件时,会出现此错误。感谢帮助。

4

2 回答 2

2

根据消息,问题是

在 Java 虚拟机之外

在这种情况下,它可能在 Delphi 代码中。

您可能想联系 Delphi 代码的开发人员,看看他们是否可以帮助解决问题,或者自己浏览代码以查看发生了什么。该hs_err_pid4400.log文件将包含对他们有价值的信息。

无论哪种方式,如果没有 Delphi 源代码,就很难解决问题。

于 2013-04-02T12:26:24.500 回答
0

重新编辑:

我得到了解决方案。问题是“如何”制作了 DLL。下面的解决方案,我希望它可以帮助更多的人:

TESTLIB (德尔福)

library TESTLIB;
{$DEFINE TESTLIB}

uses
  System.SysUtils,
  System.Classes,
  TestInt in 'TestInt.pas', //here's my unit (interface)
  Vcl.Dialogs,
  ADODB,
  Vcl.Forms;

  {$R *.res}


function MyReturn(Test: PTest): Boolean; stdcall;
var
  ado: TADOQuery;
  con: TADOConnection;
begin
    con := TADOConnection.Create(Application);
    ado := TADOQuery.Create(Application);

    con.ConnectionString := 'Provider=SQLOLEDB.1;Password=aaa;Persist Security Info=True;User ID=aa;Initial Catalog=aa;Data Source=127.0.0.1';
    con.LoginPrompt := False;
    con.Open();

    if con.Connected = True then
        ShowMessage('connected ok')
    else
        ShowMessage('not connected');

    ado.Active := False;
    ado.Connection := con;
    ado.SQL.Clear;
    ado.SQL.Add('select lalala from table where codlala = 1');
    try
        ado.Open();
        Test^.vResult := PAnsiChar(AnsiString(ado.FieldByName('fantasia').AsString));
        Result := True;
    except
        on E: Exception do
        begin
          ShowMessage('error to open the query' + #13 + 'Error: ' + E.Message);
          Result := False;
        end;
    end;
end;

exports MyReturn;

begin
end.

接口 Ole32 (java)

import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.WinNT.HRESULT;
import com.sun.jna.win32.StdCallLibrary;

public interface Ole32 extends StdCallLibrary {

    Ole32 INSTANCE = (Ole32) Native.loadLibrary("Ole32", Ole32.class);

    public HRESULT CoInitialize(Pointer p);

    public HRESULT CoUninitialize();

}

特别感谢 kobik 和 technomage 关于CoInitialize

帮助我的链接:

Delphi ISAPI App 的应用程序初始化部分中的 TADOConnection 失败:

添加 CoInitializing 常量并改进文档

通过 JNA 从 Java 使用 COM

于 2013-04-02T16:08:30.547 回答