通过gcc[works]和g++[失败]对C dll的Java调用

通过gcc[works]和g++[失败]对C dll的Java调用,java,c++,c,gcc,g++,Java,C++,C,Gcc,G++,我尝试调用这个名为TEST.C的最小虚拟C程序: void Java_TEST_run(){} 从这个名为Example.Java的Java代码中: public class Example { public static void main(String args[]) { System.out.println("START"); TEST test = new TEST(); test.dll_call

我尝试调用这个名为TEST.C的最小虚拟C程序:

void Java_TEST_run(){}
从这个名为Example.Java的Java代码中:

public class Example 
{
    public static void main(String args[]) 
    {
      System.out.println("START");   

      TEST test = new TEST(); 

      test.dll_call();

      System.out.println("ALL DONE!");      
    }   
}    

class TEST
{
    public void dll_call()
    {
      run();       
    }
    static {
        try {
            System.out.println("Load DLL = start ");

            System.load("/home/user/Desktop/TEST.dll");

            System.out.println("Load DLL = finish ");
        } catch (UnsatisfiedLinkError e) {
          System.err.println("Native code library failed to load.\n");
          System.exit(1);
        }
      }
     public native void run();    
}
如果我使用gcc进行编译,那么一切都很好:

gcc -c  TEST.c
g++ -shared  -o TEST.dll TEST.o
但如果我使用g++进行编译,如下所示:

g++ -c  TEST.c
g++ -shared  -o TEST.dll TEST.o
在运行Java示例时,我收到以下错误输出:

START
Load DLL = start 
Load DLL = finish 
Exception in thread "main" java.lang.UnsatisfiedLinkError: 'void TEST.run()'
    at TEST.run(Native Method)
    at TEST.dll_call(Example.java:21)
    at Example.main(Example.java:9)
我的操作系统是Ubuntu 18.04和openjdk 11.0.6

我对Java非常陌生,对上面的问题非常迷茫。C代码是我所能想象的最小的,不包括任何参数、头或JNI。编译和链接同时适用于gcc和g++,但在执行时会找到g++编译的DLL,但会创建不满意的链接错误。我假设g++编译可能会更改函数名Java\u TEST\u run。我尝试了许多不同名字的组合,但没有成功

如果有人能在这个问题上给我启发或暗示,我非常感谢你的帮助

非常感谢,,
马丁

< P> C和C++是不同的语言,遵循不同的编译规则。如果用G++编译,那么代码将被视为C++而不是C++。 C++做了一件称为名称混乱的事情:将函数名和变量名编码为唯一的名称,以便链接器可以分离语言中的常用名称。多亏了它,像函数重载这样的特性才成为可能

让我们考虑一个例子:

int f void{return 1;} int f int{返回0;} void g void{int i=f,j=f0;} 编译器可将上述内容更改为:

int_uuf_uv{return 1;} int{return 0;} void{int i={uu f_v,j={uu f_i0;} 尽管g的名称是唯一的,但它仍然被损坏。名称的缩进适用于所有C++符号。

如果你想防止名字的篡改,你需要使用块,但是上面的例子会导致错误,因为C没有函数重载。

< P>如在另一个答案中解释的,这个失败的原因是C++编译器的名字篡改。

为了解决这个问题,即使C++与java JNI一起工作,需要用C++的外部声明来修饰C++函数:

外部C 无效Java_测试_运行{}
这回答了你的问题吗?非常感谢,这对我很有用!谢谢你,我同意这似乎与“弄脏”这个名字有关。我尝试了一些组合,包括跑步,但对我来说没有效果。。。不管怎样,externC命令成功了。