2012-06-19 6 views
3

JNA를 사용하여 Java에서 C 라이브러리를 호출합니다. 방법이가하는 즉,이 포인터의 배열 구조체 것으로 예상JNA (Java) : 구조체에 포인터 배열을 전달하는 방법은 무엇입니까?

void printStructArray(SomeStruct **someStruct, int arraySize); 

: 내 C 코드에서

내가 가진

void printStructArray(SomeStruct **someStruct, int arraySize) { 
    for(int i = 0; i < arraySize; i++) { 
     cout << "someStruct: " << someStruct[i]->aLong << " " << someStruct[i]->aString << " " << someStruct[i]->aDouble << endl; 
    } 
} 

그냥 장난감 예,하지만 나는이 실제 라이브러리에 대해 이야기하고 싶습니다. 같은 유형의 인수가 필요하지만, 장난감 예제를 사용하면 여기에서 설명하기가 더 쉽다고 생각합니까?

모든 것을 시도했지만 (JNA에서이 함수를 선언하고 (ii) JNA에서이 함수를 호출하는 방법을 잘 모르겠습니다.

내 최신 (실패) 시도는 다음과 같습니다

SomeStruct.byReference[] structs = new SomeStruct.byReference[]{ 
     new SomeStruct.byReference(123,"hey!",1.23), 
     new SomeStruct.byReference(456,"cool!",1.45), 
     new SomeStruct.byReference(789,"world!",1.67) }; 
PointerByReference pointerByReference = new PointerByReference(structs[0].getPointer()); 
JniTest.instance.printStructArray(pointerByReference, 3); 

이가 SIGSEGV가 발생합니다.

대안 :

void printStructArray(SomeStruct.byReference[] someStructarray, int num); 

이것으로 '0'을 제공한다 :

SomeStruct.byReference[] structs = new SomeStruct.byReference[]{ 
    new SomeStruct.byReference(123,"hey!",1.23), 
    new SomeStruct.byReference(456,"cool!",1.45), 
    new SomeStruct.byReference(789,"world!",1.67) }; JniTest.instance.printStructArray(structs, 3); 

방법과 마찬가지로 선언

SomeStruct.byReference[] structs = (SomeStruct.byReference[]) new SomeStruct().toArray(new SomeStruct.byReference[]{ 
     new SomeStruct.byReference(123,"hey!",1.23), 
     new SomeStruct.byReference(456,"cool!",1.45), 
     new SomeStruct.byReference(789,"world!",1.67) }); 
PointerByReference pointerByReference = new PointerByReference(structs[0].getPointer()); 
JniTest.instance.printStructArray(pointerByReference, 3); 

이 또한 시도 ArrayStoreException를에게 원인 그만큼 좋은 점은 충돌이 아니지만 올바른 동작을 제공하지는 않지만 함수의 출력입니다.

생각하십니까?

+0

이것은 C++이므로 JNA를 사용하여 호출하기 전에 C 인터페이스에 C 인터페이스 라이브러리를 작성하지 않아도됩니까? –

+0

Java 태그가 필요한 이유는 무엇입니까? –

+0

@JimGarrison : 그는 JNI 또는 JNA를 통해 Java에서 C++ 코드를 호출하는 것에 대해 질문합니다. 그렇습니다. 이는 Java와 관련되어 있습니다. –

답변

0

결국 나는이 문제에 대한 해결책을 찾지 못했습니다. 내가 한 것은 포인터를 필요로하지 않고 JNA를 사용하여 링크하기 매우 쉬운 Java에 대한 아주 간단한 인터페이스를 제공하는 C에서 래퍼 인터페이스를 작성하여 해결 방법을 제시 한 것입니다. 이것은 꽤 잘 작동하고 포인터 작업을 시도하는 것보다 노력이 적었습니다. 직접 연결하는 몇 가지 매우 복잡한 JNA 구현을 작성하는 것보다 시간의 측면에서,이 작업을 얻기 위해 많은에게 적은 노력을 보였다

int createHandle() 
void doSomething(int handle) 
void releaseHandle(int handle) 

:

그래서, 내 인터페이스는 같은 것을 보았다 기본 c 인터페이스.

다른 장점은 이것이 C++ 라이브러리에 연결하기 쉽다는 것입니다. 이렇게하면 C++ 인터페이스가 연결하기 쉬운 c 인터페이스로 래핑됩니다.

0

이 C 또는 C++입니까?

C 인 경우 다음과 같이 calloc/malloc을 사용하여 구조체에 대한 이중 포인터를 할당하는 것이 어떻습니까?

somestruct = (SomeStruct **)calloc(arraySize, sizeof(SomeStruct *)); 

for (i = 0; i < arraySize; i++) 

    somestruct[i] = (SomeStruct *)calloc(1, sizeof(SomeStruct)); 

이제 구조를 원하는대로 채울 수 있습니다.

+0

'cout << something'을 사용하면 아마도 C가 아닐 것이라고 생각하게됩니다. ;-) –

+0

아마도 모든'->'연산자! –

+0

"C로"설명을 시작한 것 같으므로 JNA에 대한 간단한 설명을 추가했습니다. C의 질문입니다 .-D –

2

Structure.ByReference의 배열을 전달하는 것으로 충분합니다. 배열의 주소가 원시 코드로 전달됩니다. JNA는 함수 호출 후에 범위를 벗어나는 포인터 배열에 대한 공간을 자동으로 할당합니다.

PointerByReference는 포인터 값을 참조로 전달하기위한 것입니다 (즉, 호출 수신자가 값을 변경할 수 있음). 이 경우 이 아니며이 아닙니다.

+0

아, 재미 있습니다. 나는 이것을 지금 시도 할 것이다. –

+0

시도해보고 결과를 문제 설명에 추가했습니다. 나는 이것을 잘못 구현했을지도 모른다. 내 구현에서는이 충돌하지 않지만 C 함수를 밖으로 구조를 인쇄하지 않습니다, 그냥 "0"인쇄합니다. –

+0

네이티브 함수 호출 전에 Java 메모리를 네이티브 메모리에 동기화하려면 Structure.write()를 호출해야합니다. 대부분의 경우, JNA는 이것을 필요로 할 때 자동 검출 할 수 있습니다 만,이 경우에는 분명히 없습니다. 네이티브 호출 이전에 각 배열 요소에 대해 Structure.write()를 호출하면 적절한 결과를 얻을 수 있는지 확인하십시오. – technomage

2

방금 ​​JNA 대신 BridJ를 사용하는 것이 효과적이라는 솔루션을 발견했습니다. 어쩌면 JNA를 작동시킬 수있는 방법이있을 수도 있지만, 분명하지는 않습니다.BridJ 정말 사용하기 쉬운 :

선언 :

public static native void printStructArray(Pointer<Pointer<SomeStruct > > someStruct, int arraySize); 

사용법 : 그것은 그들이 값에 의해 지원 구조를 해달라고 것,하지만 난 내 현재의 인터페이스에서 값에 의한 구조를 가지고 있겠지

Pointer<Pointer<SomeStruct>> pointers = Pointer.allocatePointers(SomeStruct.class, 3); 
pointers.set(0, Pointer.pointerTo(new SomeStruct().aDouble(1.58).aLong(5432).aString(Pointer.pointerToCString("Wheee!")))); 
pointers.set(1, Pointer.pointerTo(new SomeStruct().aDouble(1.58).aLong(5432).aString(Pointer.pointerToCString("Wheee!")))); 
pointers.set(2, Pointer.pointerTo(new SomeStruct().aDouble(1.58).aLong(5432).aString(Pointer.pointerToCString("Wheee!")))); 
JnitestLibrary.printStructArray(pointers, 3); 

, 그래서 그것은 지금 나에게 문제가되지 않는다. 분명히 성능은 좋지만 개인적으로 성능을 테스트하지는 않았습니다.

저는 아직 JNA 솔루션에 개방되어 있고, 문제에 대한 JNA 솔루션을 제공 할 수있는 사람이라면 누구나 똑딱 거릴 것입니다.

관련 문제