У меня следующий Java код, сгенерированный с помощью SWIG. Хотя SWIG использовался для генерации кода, знание SWIG не требуется для понимания этого вопроса
Код пользователя Java:
public class UuidUtil implements OCUuidUtilConstants {
public static Uuid generateUuid() {
long cPtr = UuidUtilJNI.generateUuid();
return (cPtr == 0) ? null : new Uuid(cPtr, true);
}
}
UuidUtilJNI.generateUuid()
определяется следующим образом
Java код вызова кода JNI
public class UuidUtilJNI {
public final static native long generateUuid();
}
SWIG-генерируемый код оболочки JNI C uuid_wrap.c
uuid_t * jni_gen_uuid()
{
printf("Inside jni_gen_uuid\n");
uuid_t *value = (uuid_t *)malloc(sizeof(uuid_t));
printf("Calling gen_uuid\n");
gen_uuid(value);
return value;
}
SWIGEXPORT jlong JNICALL Java_UuidUtilJNI_generateUuid(JNIEnv *jenv, jclass jcls) {
jlong jresult = 0 ;
uuid_t *result = 0 ;
(void)jenv;
(void)jcls;
result = (uuid_t *)jni_gen_uuid();
*(uuid_t **)&jresult = result;
return jresult;
}
частичный C код для gen_uuid(uuid_t *uuid)
function uuid.c
void gen_uuid(uuid_t *uuid)
{
printf("Inside gen_uuid\n");
/* code to set the uuid to type 4 UUID according to RFC4122 */
}
Я тестирую его следующим образом:
@Test
public void generateAndConvert() {
Uuid testUuid = UuidUtil.generateUuid();
assertNotNull(testUuid);
// other test code left out for readability
}
Когда тест выполняется на Windows, код работает как положено.
Когда я пытаюсь запустить тот же код на Linux, тест зависает.
Он печатает 2 из 3 найденных в коде строк печати.
Inside jni_gen_uuid
Calling gen_uuid
строка Inside gen_uuid
никогда не вызывается при запуске теста на компьютере Linux (Fedora 30).
Сначала я подумал, что в выводе объектных файлов было какое-то несоответствие, что приводило к сбою кода оболочки, когда вызывая код UUID. Я сравнил флаги сборки, используемые для построения кода uuid.c
и uuid_wrap.c
, и они используют те же флаги, за исключением того, что некоторые предупреждения о сборке отключены для кода оболочки, поскольку он генерируется инструментом и не предназначен для быть измененным мной.
Я действительно не знаю, где еще искать.
Я проверил файл uuid.o, используя nm и objdump, насколько я могу сказать, что он имеет символ gen_uuid .
Мне не удалось правильно подключить gdb к работающему образцу, поэтому я не уверен, что это даст какую-либо полезную информацию.
Есть предложения, которые могут помочь найти проблему?