Вызов dll-метода C ++ из Java с использованием JNA и избежание искажения имени метода

Я просматривал ссылки на StackOverflow о том, как решить проблему искажения имени метода, но не нашел никакого решения с примером в реальном времени.

Сценарий-A Файл C ++ Ex.dll предоставляется клиентом. Мне нужно получить доступ к Ex.dll и вызвать методы в том же через Java.

Ограничения — не могу изменить Ex.dll, я могу получить доступ только к тому же.

Проблема столкнулась — Получение ниже исключение, когда я получаю доступ к Ex.dll через JNA

Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'getCPUSpeed': The specified procedure could not be found.
at com.sun.jna.Function.<init>(Function.java:134)
at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:336)
at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:316)
at com.sun.jna.Library$Handler.invoke(Library.java:203)
at $Proxy0.getCPUSpeed(Unknown Source)
at cpp.java.JnaTest.main(JnaTest.java:16)

Много погуглил и обнаружил, что это связано с именем метода Mangling, но опять же не смог найти ни одного хорошего примера кода с решением.

Это код, который я использовал

import com.sun.jna.Native;
class JnaTest
{

public static void main(String args[])
{
try
{
JnaInterface jInterface = (JnaInterface) Native.loadLibrary("Ex", JnaInterface.class);

System.out.println("Calling C++ DLL method");
System.out.println("========================");
System.out.println("getCPUSpeed() -- "+jInterface.getCPUSpeed());

} catch (Exception e) {
e.printStackTrace();
}
}
}package cpp.java;
import com.sun.jna.Library;
public interface JnaInterface extends Library{
public int getCPUSpeed();
}

Обновление 1: **************************************

Ниже упоминаются фактические функции, которые я получаю, когда просматриваю DBMM.dll через обходчик зависимостей.

DBMM DLL функции-

??0cDbmmInterfaceCache @@ QAE @ ABV0 @@ Z

??0cDbmmInterfaceCache @@ QAE @ XZ

??0cDbmmInterfaceControl @@ QAE @ ABV0 @@ Z

??0cDbmmInterfaceControl @@ QAE @ XZ

??0cDbmmInterfaceEcon @@ QAE @ ABV0 @@ Z

??0cDbmmInterfaceEcon @@ QAE @ XZ

??0cDbmmInterfaceKnob @@ QAE @ XZ

??0cDbmmInterfaceOutput @@ QAE @ ABV0 @@ Z

??0cDbmmInterfaceOutput @@ QAE @ H @ Z

??0cDbmmInterfacePoolLoan @@ QAE @ ABV0 @@ Z

??0cDbmmInterfacePoolLoan @@ QAE @ V? $ Basic_string @ DU? $ Char_traits @ D @ станд @@ V? $ Распределитель @ D @ 2 @@ станд @@@ Z

??0cDbmmMacroEcon @@ QAE @ ABV0 @@ Z

??0cDbmmMacroEcon @@ QAE @ ABVcDbmmInterfaceEcon @@ _ N @ Z

??0cDbmmMtgBasisConstSpreadModel @@ IAE @ XZ

??0cDbmmMtgBasisConstSpreadModel @@ QAE @ ABV0 @@ Z

??0cDbmmMtgBasisConstSpreadModel @@ QAE @ PBD @ Z

??0cDbmmMtgBasisModel @@ QAE @ ABV0 @@ Z

??0cDbmmMtgBasisModel @@ QAE @ XZ

??0cScaleFieldsSubSum @@ QAE @ NN @ Z

??1cDbmmInterfaceCache @@ QAE @ XZ

??1cDbmmInterfaceControl @@ QAE @ XZ

??1cDbmmInterfaceEcon @@ QAE @ XZ

??1cDbmmInterfaceKnob @@ QAE @ XZ

??1cDbmmInterfaceOutput @@ QAE @ XZ

??1cDbmmInterfacePoolLoan @@ QAE @ XZ

??1cDbmmMacroEcon @@ QAE @ XZ

??1cDbmmMtgBasisConstSpreadModel @@ ОАЭ @ XZ

??1cDbmmMtgBasisModel @@ ОАЭ @ XZ

??1cScaleFieldsSubSum @@ QAE @ XZ

??4cDbmmInterface @@ QAEAAV0 @ ABV0 @@ Z

??4cDbmmInterfaceCache @@ QAEAAV0 @ ABV0 @@ Z

??4cDbmmInterfaceControl @@ QAEAAV0 @ ABV0 @@ Z

??4cDbmmInterfaceEcon @@ QAEAAV0 @ ABV0 @@ Z

??4cDbmmInterfaceKnob @@ QAEAAV0 @ ABV0 @@ Z

??4cDbmmInterfaceOutput @@ QAEAAV0 @ ABV0 @@ Z

??4cDbmmInterfacePoolLoan @@ QAEAAV0 @ ABV0 @@ Z

??4cDbmmMacroEcon @@ QAEAAV0 @ ABV0 @@ Z

??4cDbmmMtgBasisConstSpreadModel @@ QAEAAV0 @ ABV0 @@ Z

??4cDbmmMtgBasisModel @@ QAEAAV0 @ ABV0 @@ Z

??4cScaleFieldsSubSum @@ QAEAAV0 @ ABV0 @@ Z

??_7cDbmmMtgBasisConstSpreadModel @@ 6В @

??_7cDbmmMtgBasisModel @@ 6В @

??_FcDbmmInterfaceOutput @@ QAEXXZ

??_FcDbmmInterfacePoolLoan @@ QAEXXZ

??_FcScaleFieldsSubSum @@ QAEXXZ

?Добавить @ cScaleFieldsSubSum @@ QAEXNN @ Z

?InitSubsum @ cScaleFieldsSubSum @@ QAEXNN @ Z

?REINIT @ cDbmmMacroEcon @@ QAEX_N @ Z


Не уверен, как я могу вызвать эти функции через Java.

Спасибо, если кто-нибудь может предоставить мне решение с конца Java, с примером кода, пожалуйста 🙂

1

Решение

Ваша функция украшена соглашениями JNI и stdcall; это не C ++ — покалеченный.

Похоже, библиотека является библиотекой JNI, учитывая Java_sysInfo_ префикс. Если это так, вам нужно только объявить эквивалентную сторону Java, например,

// default package
public class sysInfo {
static { System.loadLibrary("Ex"); }
public static native int getCPUSpeed();
}

Я думаю, вы, вероятно, обнаружите, что это отображение является правильным и что вам не нужен JNA.

РЕДАКТИРОВАТЬ

Имеется класс C ++ с произвольным входным аргументом ctor и метод getCount():

extern "C" int getCountForName(const char* name) {
MyCPPClass mycpp(name);
return mycpp.getCount();
}

Скомпилируйте это в общую библиотеку, и загрузить через JNA.

0

Другие решения

Если вы собираете библиотеку DLL с помощью Visual studio, вы должны иметь возможность собирать ее как релиз, а не как отладку, чтобы исправить имена функций, если вы этого еще не сделали.

0

По вопросам рекламы [email protected]