2011-09-24 5 views
10

JNI를 사용하여 C++과 Java간에 데이터를 전달하고 있습니다. 나는 '긴'유형을 통과해야하고, 같은 것을 사용하여 그렇게하고 다음 '긴'매개 변수를 검색 할 때 JNI에 C++ long 유형 변환하기 jlong ​​

long myLongVal = 100; 
jlong val = (jlong)myLongVal; 
CallStaticVoidMethod(myClass, "(J)V", (jvalue*)val); 

그러나 자바에서, 그것은 매우 큰 음수로 검색됩니다합니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까?

+2

'long! = jlong' 어쩌면? – quasiverse

+0

JNI를 통해 "1"의 값을 전달하면 Java가 흥미롭게도 4294967297에 계속 보관됩니다. 그 숫자는 페르마 숫자입니다. 그건 우연히 우연의 일치로 보입니다. 이 특정한 가치가 왜 드러났는지에 대한 아이디어가 있다면 누구나 듣고 싶습니다. 화제로 돌아가서 Java/JNI가 정확한 값 1로 해석 할 수 있도록'(jlong) value '로 오랫동안 형변환했다. – StockB

+1

4294967297은 (1 << 32) + 1 – samgak

답변

12

jlong ​​(64 비트)을 포인터 (대개 32 비트 임)로 전달하면 반드시 데이터가 손실됩니다. 나는 컨벤션 무엇 모르겠지만, 하나이 시도 :

CallStaticVoidMethodA(myClass, "(J)V", (jvalue*)&val); //Note address-of! 

나이 :

CallStaticVoidMethod(myClass, "(J)V", val); 

그것은 jvalue 배열을 ...A 방법이다가, 노 후위 방법은 스칼라에 C 등가물을 Java 유형.

첫 번째 스 니펫은 다소 안전하지 않습니다. 더 나은, 경우 더 자세한 대안은 다음과 같습니다

이국적인 CPU의 archtectures에
jvalue jv; 
jv.j = val; 
CallStaticVoidMethodA(myClass, "(J)V", &jv); 

, jlong 변수와 jvalue 노동 조합에 대한 정렬 요구 사항이 다를 수 있습니다. union을 명시 적으로 선언하면 컴파일러가이를 처리합니다.

또한 C++ long 데이터 유형은 종종 32 비트입니다. jlong은 64 비트이고, 32 비트 플랫폼에서 비표준 C 코드는 long long 또는 __int64입니다.

+3

이다. "C++ long은 32 비트이다."- 일부 아키텍처에는 유념하고 다른 아키텍처에는 유념하지 마십시오. x64 리눅스는 일반적으로 64 비트 길이를 사용합니다. long long은 어느 곳에서나 사용할 수 없습니다 (확장 IIRC). –

+1

사실이에요. 나는 자격을 추가 할 것이다. –

+0

답변 주셔서 감사합니다 - 불행히도 suggseted 접근 방식을 시도하고 매개 변수가 여전히 Java에서 검색 할 때 왜곡 된 나타납니다, 나는 또한 int 및 float 형식으로 길게뿐만 아니라 시도했다 : (이상하게 * 다음 * 않습니다 작동 및 전용 int 유형 ()'int someInt = 100; –

3
CallStaticVoidMethod(myClass, "(J)V", (jvalue*)val); 

이것은 정의되지 않은 동작입니다. 포인터가되도록 정수를 캐스팅하고 있습니다. 그것은 포인터가 아닙니다. 적어도 주소 인을 전달해야합니다. 이 코드는 대부분의 플랫폼에서 즉시 충돌합니다.

+0

당신은 절대적으로 맞습니다 - 나는 주소를 가져야합니다. 그러나 이것은 여전히 ​​저에게 효과적이지 않습니다 (float, int stypeInt = 100; CallStaticVoidMethod (myClass, "(I) V") int someType = 100; CallStaticVoidMethod (myClass, , (jvalue *) (jint) someInt) ;' –