自己的dll怎么让JAVA调用??? ( 积分: 200 )

  • 主题发起人 无头骑士
  • 开始时间

无头骑士

Unregistered / Unconfirmed
GUEST, unregistred user!
目前我用JAVA调用DLL成功,但当我的dll使用了ADO或BDE时,java程序就出错了,
dll用DELPHI的程序调用没问题,。。。
JAVA如下
package alvinJNI;
class HelloWorld {
static {
System.loadLibrary("DelphiAction");
//等一下我们就用Delphi来编一个程序,编好之后生成的文件就是 DelphiAction.dll 这是一个动态链接库文件,这个类里先在静态语句块中加载它
}
public native void printText(int i);
//声明一个 native 的本地代码程序,我们使用的是 Delphi 来编写.注意:这个方法在这里只是声明,并没有定义方法体,因为这个方法我们要用 Delphi 来实现.
public static void main(String[] args) {
//创建对象并调用里面的 native 方法.
HelloWorld hw = new HelloWorld();
hw.printText(100);
}
}

DELPHI如下:
uses
SysUtils,
Classes,
JNI,
DB, Dialogs,Forms,
DBTables;

{$R *.res}
procedure Java_alvinJNI_HelloWorld_printText(PEnv: PJNIEnv;
Obj: JObject;
i: JInt);
stdcall;
var
tmpInt: Integer;
// adoc:TADOConnection;
// adot:TADOTable;
Table1: TTable;
begin
//参数提交过来的 int 型数据,在这里是一个 JInt 数据,它其实就是一个 Integer 数据,它的使用更加方便
//它可以直接地参与 Interger 类型数据的运算,是不是很容易.
Application.Initialize;
tmpInt := i + 100;
tmpInt := tmpInt - 100;
showmessage('d');
Table1:=TTable.Create(nil);
Table1.TableName:='';
Table1.DatabaseName:='DBDEMOS';
Table1.TableName:='biolife.db';
Table1.Open;
while not Table1.Eof do
begin

showmessage(Table1.FieldByName('Category').AsString);
Table1.Next;
end;
{ adoc:=TADOConnection.Create(nil);
adot:=TADOTable.Create(nil);
adoc.LoginPrompt:=False;
adoc.ConnectionString:='Provider=SQLOLEDB.1;Password=soft_778899;Persist Security Info=True;User ID=sa;Initial Catalog=qhsw;Data Source=.';
adot.Connection:=adoc;
adoc.Open;
adot.TableName:='tree';
adot.Open;
while not adot.Eofdo
begin
showmessage(adot.FieldByName('name').AsString);
adot.Next;
end;
}
end;

exports
Java_alvinJNI_HelloWorld_printText;
begin
// CoInitialize(NULL);
// initialization//保留字,你可查一下帮助看其出现的具体位置
// Coinitialize;
//finalization
// CoUninitialize;
// Application.initialize(nil);
end.

错误提示就是说:没有Coinitialize之类的。
 
提示说得很清楚,按照提示做就可以了[:D]
 
兄弟,请看看这个贴子:c#调用delphi的
注意CoInitialize(nil);CoUnInitialize();的位置
http://galileoworld.blogcn.com/diary,9044701.shtml
 
ADO是COM组件.
DLL或者线程在调用COM之前一定要CoInitialize.结束的时候CoUnInitialize.
不明白你为啥把调用这里的代码注释掉
 
谁还能回答一下啊?????
昨晚我已经试出可以用BDE了,但是ADO根本没法用,因为COM组件我不知道在JAVA中怎么Coinitialize,
楼上的我就是不注释,一样的错误 ,这个初始化COM的不是在DLL中,而是在调用程序中,而JAVA中我不知道怎么初始化。
 
大哥,你仔细看http://galileoworld.blogcn.com/diary,9044701.shtml
这个贴子了吗?在你开始使用ADO对象前调用CoInitialize(nil);
函数退出前调用CoUnInitialize();
一点问题都没有。。。。
 
不需要在java里面调.而是在Delphi的DLL的初始化的时候调一下.
 
楼上的你试过了吗?我可是试过后得出的结论。
 
JNI调Delphi的DLL,DLL中用了COM技术.
好几年以前我就用过了
 
楼上对你无语。。。
 
给你一个例子:
library TrimResDeviceInDll;
{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
{%File '../Common/JNI_MD.INC'}
uses
SysUtils,
Classes,
Db,
ADODB,
Windows,
ActiveX,
UnitCommon in '../Common/UnitCommon.pas' {PubDb: TDataModule},
JNI in '../Common/JNI.pas';
{$R *.RES}
const
xs = 1;
//闲时
ms = 2 ;
//忙时
pl = 3 ;
//疲劳
tf = 4;
//突发
var
iNextms,iNextxs,iNextpl,iNexttf: integer;
iRackNextms,iRackNextxs,iRackNextpl,iRackNexttf: integer;
gRecordListms,gRecordListxs,gRecordListpl,gRecordListtf: TStringList;
vsRecord : string;
bInit: boolean = False;
function initData: PChar;
var
ADOQuery1: TADOQuery;
vSqlms,vSqlxs,vSqlpl,vSqltf: string;
begin
//CoInitialize(nil);
ADOQuery1 := TADOQuery.Create(nil);
// ADOQuery1.ConnectionString := 'Provider=MSDASQL.1;Password=ctgrms;Persist Security Info=True;User ID=rms;Data Source=cttest';
ADOQuery1.Connection := TPubDb.Create(nil).Conn;
iNextms := 0;
iNextxs := 0;
iNextpl := 0;
iNexttf := 0;
iRackNextms := 1;
iRackNextxs := 1;
iRackNextpl := 1;
iRackNexttf := 1;
//忙时设备
vSqlms := 'select ID from rms.device where id>=200011 and id<=200051 order by ID';
//闲时设备
vSqlxs := 'select ID from rms.device where id>=200002 and id<=200011 order by ID';
//突发设备
vSqltf := 'select ID from rms.device where id>=200100 and id<=200400 order by ID';
//疲劳设备
vSqlpl := 'select ID from rms.device where id>=200052 and id<=200092 order by ID';
try
// 忙时设备
ADOQuery1.Active := False;
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add(vSqlms);
ADOQuery1.Active := True;
ADOQuery1.First;
while not ADOQuery1.eofdo
begin
vsRecord := ADOQuery1.Fields[0].AsString;
gRecordListms.Add(vsRecord);
ADOQuery1.Next;
end;

try
ADOQuery1.First;
//没有这个会出错
ADOQuery1.Active := False;
ADOQuery1.SQL.Clear;
except
end;
// 闲时设备
ADOQuery1.SQL.Add(vSqlxs);
ADOQuery1.Active := True;
ADOQuery1.First;
while not ADOQuery1.eofdo
begin
vsRecord := ADOQuery1.Fields[0].AsString;
gRecordListxs.Add(vsRecord);
ADOQuery1.Next;
end;

try
ADOQuery1.First;
ADOQuery1.Active := False;
ADOQuery1.SQL.Clear;
except
end;
//突发设备
ADOQuery1.SQL.Add(vSqltf);
ADOQuery1.Active := True;
ADOQuery1.First;
while not ADOQuery1.eofdo
begin
vsRecord := ADOQuery1.Fields[0].AsString;
gRecordListtf.Add(vsRecord);
ADOQuery1.Next;
end;

try
ADOQuery1.First;
ADOQuery1.Active := False;
ADOQuery1.SQL.Clear;
except
end;
//疲劳设备
ADOQuery1.SQL.Add(vSqlpl);
ADOQuery1.Active := True;
ADOQuery1.First;
while not ADOQuery1.eofdo
begin
vsRecord := ADOQuery1.Fields[0].AsString;
gRecordListpl.Add(vsRecord);
ADOQuery1.Next;
end;

try
ADOQuery1.First;
ADOQuery1.Active := False;
ADOQuery1.SQL.Clear;
except
end;
finally
ADOQuery1.Free;
end;
end;

function initDeviceData: PChar;
stdcall;
begin
if not bInit then
begin
gRecordListms := TStringList.Create;
gRecordListms.Clear;
gRecordListxs := TStringList.Create;
gRecordListxs.Clear;
gRecordListtf := TStringList.Create;
gRecordListtf.Clear;
gRecordListpl := TStringList.Create;
gRecordListpl.Clear;
initData;
bInit := true;
end;
end;
//忙时设备
function getDeviceRackIDms: Pchar;
stdcall;
begin
initDeviceData;
if iNextms < gRecordListms.Count then
begin
vsRecord := gRecordListms.Strings[iNextms];
vsRecord := vsRecord + ',' + inttostr(iRackNextms);
Result := Pchar(vsRecord);
end
else
begin
iNextms := 0;
inc(iRackNextms);
vsRecord := gRecordListms.Strings[iNextms];
vsRecord := vsRecord + ',' + inttostr(iRackNextms);
Result := Pchar(vsRecord);
end;
inc(iNextms);
end;
//闲时设备
function getDeviceRackIDxs: PChar;
stdcall;
begin
initDeviceData;
if iNextxs < gRecordListxs.Count then
begin
vsRecord := gRecordListxs.Strings[iNextxs];
vsRecord := vsRecord + ',' + inttostr(iRackNextxs);
Result := Pchar(vsRecord);
end
else
begin
iNextxs := 0;
inc(iRackNextxs);
vsRecord := gRecordListxs.Strings[iNextxs];
vsRecord := vsRecord + ',' + inttostr(iRackNextxs);
Result := Pchar(vsRecord);
end;
inc(iNextxs);
end;
//突发设备
function getDeviceRackIDtf: PChar;
stdcall;
begin
initDeviceData;
if iNexttf < gRecordListtf.Count then
begin
vsRecord := gRecordListtf.Strings[iNexttf];
vsRecord := vsRecord + ',' + inttostr(iRackNexttf);
Result := Pchar(vsRecord);
end
else
begin
iNexttf := 0;
inc(iRackNexttf);
vsRecord := gRecordListtf.Strings[iNexttf];
vsRecord := vsRecord + ',' + inttostr(iRackNexttf);
Result := Pchar(vsRecord);
end;
inc(iNexttf);
end;
//疲劳设备
function getDeviceRackIDpl: PChar;
stdcall;
begin
initDeviceData;
if iNextpl < gRecordListpl.Count then
begin
vsRecord := gRecordListpl.Strings[iNextpl];
vsRecord := vsRecord + ',' + inttostr(iRackNextpl);
Result := Pchar(vsRecord);
end
else
begin
iNextpl := 0;
inc(iRackNextpl);
vsRecord := gRecordListpl.Strings[iNextpl];
vsRecord := vsRecord + ',' + inttostr(iRackNextpl);
Result := Pchar(vsRecord);
end;
inc(iNextpl);
end;

function RecordFree: PChar;
begin
if gRecordListms <> nil then
gRecordListms.Free;
if gRecordListxs <> nil then
gRecordListxs.Free;
if gRecordListtf <> nil then
gRecordListtf.Free;
if gRecordListpl <> nil then
gRecordListpl.Free;
end;

procedure DllEntryPoint(dwReason:DWord);
begin
case dwReason of
//在进程启动或调用LoadLibrary时
DLL_PROCESS_ATTACH:
begin
CoInitialize(nil);
initDeviceData ;
end;
//进程终止或调用FreeLibrary时
DLL_PROCESS_DETACH:
begin
RecordFree;
CoUnInitialize;
end;
//进程已经调用DLL并且创建一个新线程时
DLL_THREAD_ATTACH:;
//进程已经调用DLL并且一个线程终止时
DLL_THREAD_DETACH:;
end;
end;
function Java_Actions_getDeviceRackID(PEnv: PJNIEnv;
Obj: JObject;
iType: JInt ):JString ;stdcall;
var
JVM: TJNIEnv;
begin
JVM := TJNIEnv.Create(PEnv);
case iType of
xs: //闲时
Result :=JVM.StringToJString(getDeviceRackIDXs);
ms : //忙时
Result := JVM.StringToJString(getDeviceRackIDMs);
pl : //疲劳
Result := JVM.StringToJString(getDeviceRackIDPl);
else
Result := JVM.StringToJString(getDeviceRackIDPl);
end;

end;
exports
//initDeviceData,
Java_Actions_getDeviceRackID,
getDeviceRackIDms,
getDeviceRackIDxs,
getDeviceRackIDpl,
getDeviceRackIDtf;
//RecordFree;
begin
DLLProc:=@DllEntryPoint;
DllEntryPoint(DLL_PROCESS_ATTACH);
end.
 
为什么我运行JAVA类程序 可以打开数据库,运行正确,
而我用在JAVABEAN中,TOMCAT就关掉了呢??????好烦啊。。谁来帮我解惑???
 

Similar threads

D
回复
0
查看
787
DelphiTeacher的专栏
D
D
回复
0
查看
817
DelphiTeacher的专栏
D
顶部