次の問題を何日も解決しようとしています。特定のネイティブ関数の実行中に JNA プログラムがハングし、デバッグにより、JNA ソース内の特定の場所でプログラム制御が失われることが示されます。詳細はこちら。JNAでアクセスしようとしているDLLに3つのネイティブ関数があります。それらは次のとおりです
DllExport long calculatePayment(...,Protection protectionArr[PROTECTION_SIZE],
Others othersArr[OTHERS_SIZE],RC rcArr[RC_SIZE], ...);
DllExport long bufferCalculatePayment(const char *inputBuffer, char **OutputBuffer);
DllExport long fileCalculatePayment(const char *InputFile, const char *OutputFile);
対応する Java インターフェイスのマッピングは次のとおりです。
public interface DLLInterface extends Library {
public DLLInterface INSTANCE = (DLLInterface) Native.loadLibrary("DLLInterface",
DLLInterface.class);
/* Others Structure is as follows.. protection and rc structure is similar with their
own initialize methods*/
public static final NativeLong othersSize = new NativeLong(20);
class Others extends Structure {
public static class ByValue extends Others implements Structure.ByValue {
}
public double amt = 0.00;
public NativeLong flag = new NativeLong();
public byte[] details = new byte[50]; //
public byte[] mDetails = new byte[50];
public NativeLong flag2 = new NativeLong();
public static Structure[] initialize() {
Others result = new Others();
Others[] resultArr = (Others[]) result.toArray(othersSize);
return resultArr;
}
public void setDetails(String dataIn) {
Arrays.fill(details, (byte) 0);
if (dataIn != null) {
String data = dataIn;
if (data.length() > 49) {
data = data.substring(0, 49);
}
byte[] bytes = data.getBytes();
System.arraycopy(bytes, 0, details, 0, bytes.length);
}
}
//other set functions here
@Override
protected List getFieldOrder() {
return Arrays.asList("amt", "flag", "details", "mDetails", "flag2");
}
}
//Protection and RC sturcutre are similar. Both structures contain fields
of the type byte[] and double.
//Prototypes for native functions
NativeLong calculatePayment(.....Structure[] protectionArr, Structure[]
othersStruct , Structure[] rcArr,.....) ;
Nativelong bufferCalculatePayment(Strubg inputBuffer, PointerByReference
OutputBuffer);
Natuvelong fileCalculatePayment(String InputFile, String OutputFile);
}
//In main function I am calling these functions as follows -
public static void main(String args[]){
DLLInterface.Others[] othersArr = (DLLInterface.Others[])
DLLInterface.Others.initialize();
DLLInterface.RC[] rcArr = (DLLInterface.RC[]) DLLInterface.RC.initialize();
DLLInterface.Protection[] protectionArr = (DLLInterface.Protection[])
DLLInterface.Protection.initialize(); //static method
...
//passing values to structures
...
//few native functions calls goes here (they get executed successfully
NativeLong y =
DLLInterface.INSTANCE.calculatePayment(....protectionArr,othersArr,rcArr, ...);
String inputBuffer = ""<?xml version= \"1.0\" ?><ROOT><REQ><TRANSACT>
<ID>12345</ID><METHOD>COMPOUND</METHOD><AMT>50000</AMT><TERM>360</TERM></TRANSACT>
</REQ></ROOT>";
NativeLong b = DLLInterface.INSTANCE.bufferCalculatePayment(inputBuffer,pRef);
DLLInterface.INSTANCE.fileCalculatePayment("InFile","OutFile");
}
3つの関数すべてでプログラムがハングします..決して終了しないので、コードをデバッグしようとしました。次に、 Object result = invoke(args, nativeType, allowObjects) を呼び出した後、 for ループをたどるとプログラム制御が失われることがわかりました。Function.java ファイル ソース - JNA ソースから数行のソース コードをリストしました。
public Object invoke(Class returnType, Object[] inArgs, Map options){
.......
result = resultConverter.fromNative(result, context);
....
// Sync all memory which might have been modified by the native call
if (Structure.ByReference[].class.isAssignableFrom(inArg.getClass()))
{ Class type = inArg.getClass().getComponentType();
Structure[] ss = (Structure[])inArg;
for (int si=0;si < ss.length;si++) {
Pointer p =array.getPointer(Pointer.SIZE * si);
ss[si] =Structure.updateStructureByReference(type, ss[si], p);
} //////*///////////////////////*/program control gets lost after this
}.........}
何が問題になる可能性がありますか?ネイティブ関数に何か問題がありますか、それとも引数のマッピングが正しくありません。どんな助けでも大歓迎です..