如何在java中表示C++类以通过FFI使用?

问题描述 投票:0回答:1

我有以下 C++ 示例代码

class SomeClass: public ISomeClass
{
private:
    int myMember;

public:
    SomeClass(int value) : myMember(value) {}
    int GetCount() override
    {
        return myMember;
    }
};

extern "C" __declspec(dllexport)
int doSomething(ISomeClass** someCl)
{
    *someCl = new SomeClass(600);
    return (*someCl)->GetCount() + 2;
}

我在 Java 中通过 FFI 成功使用了它,代码如下:

try(Arena arena = Arena.ofConfined()) {
        Linker linker = Linker.nativeLinker();
        SymbolLookup my = SymbolLookup.libraryLookup("C:\\Path\\to\\my.dll", arena);
        MethodHandle doSomething = linker.downcallHandle(
                my.find("doSomething").orElseThrow(),
                FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.ADDRESS)
        );
        MemorySegment someAddress = arena.allocate(ValueLayout.ADDRESS);
        int res = (int)doSomething.invoke(someAddress);
        System.out.println("Result is " + res);
    }
    catch (Throwable t)
    {
        System.out.println("Error is " + t.getMessage());
    }

并且它正确输出

602

我的问题是 - 如何在 Java 中表示 C++ 的

SomeClass
,以便我可以将该表示从 Java 传递到 C++,而不是
MemorySegment someAddress
行上的
doSomething.invoke(someAddress)
,并且稍后我可以使用该表示来调用
ThatRepresentation->GetCount() 
直接在 Java 中的类上使用方法?

java c++ java-native-interface ffi java-ffm
1个回答
0
投票

您无法直接从 Java 调用

SomeClass::GetCount()
。 Java 无法从自己的角度与其他语言进行交互——这个负担都落在了其他语言身上。您唯一能做的就是在 Java 中使用
SomeClass
创建一个
native int GetCount()
类,然后在 C++ 中实现它。但是 Java 和 C++ 类是分开的,Java 对象必须存储一个指向它所包装的 C++ 类的指针。

Java 中存储指针的 TL;DR 就是:

jlong

您不能使用来自 Java 的指针,但您可以将它们传递回 C/C++。
有关更多信息,请参阅:通过 JNI 在 C 和 Java 之间传递指针

© www.soinside.com 2019 - 2024. All rights reserved.