Java 调用 GCC 编译的 C 库可以工作,但使用 G++ 编译时会失败

2024-03-23

我尝试调用这个最小的 C 代码(文件TEST.c):   void Java_TEST_run() {}
从这个Java代码(文件Example.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 -c TEST.c                     
g++ -shared -o TEST.dll TEST.o

如果我用 GCC 编译(甚至用 G++ 创建 lib!)一切正常,但如果我用 G++ 编译(g++ -c TEST.c),运行 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)

C 和 C++ 是不同的语言,遵循不同的编译规则。如果你编译g++,那么代码将被视为 C++ 而不是 C。这是常见的陷阱误解C++ 是 C 的超集。

C++ 做了一些叫做名称修改:将函数和变量名称编码为唯一名称,以便链接器可以分隔语言中的通用名称。多亏了它,诸如函数重载之类的功能才成为可能。

让我们考虑一个例子(source https://en.wikipedia.org/wiki/Name_mangling#Simple_example):

int  f (void) { return 1; }
int  f (int)  { return 0; }
void g (void) { int i = f(), j = f(0); }

编译器可以将上面的内容更改为:

int  __f_v () { return 1; }
int  __f_i (int)  { return 0; } 
void __g_v () { int i = __f_v(), j = __f_i(0); }

尽管名字是g()是独一无二的,但仍然被破坏。名称修饰适用于所有 C++ 符号。

如果你想防止名称修改,你需要使用extern "C"{} https://en.cppreference.com/w/cpp/language/language_linkage块(但上面的例子会导致错误,因为 C 没有函数重载)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 调用 GCC 编译的 C 库可以工作,但使用 G++ 编译时会失败 的相关文章

  • 如何在 javascript 中使用 .net 资源文件

    无论如何 我可以在 javascript 中访问我的资源文件 resx 吗 如果没有 那么是否有任何解决方法可以用不同语言的 javascript 显示消息 如果您的 javascript 在页面中 您可以使用 var globalReso
  • 强制预先加载原本延迟加载的属性

    我有一个 Hibernate 对象 它的属性都是惰性加载的 大多数这些属性是其他 Hibernate 对象或 PersistentSet 现在我想强制 Hibernate 一次性加载这些属性 当然 我可以 触摸 这些属性中的每一个objec
  • 使用 Mono Cecil 添加 try-catch

    我正在使用 Mono Cecil 在另一个方法中注入代码 我想在我的代码周围添加一个 Try Catch 块 所以我写了一个带有 try catch 块的 HelloWorld exe 并反编译了它 Try Catch 的 Reflecto
  • M1 MacBook Pro 和 cmake 的编译错误

    我刚刚拿到了新的 M1 MacBook Pro 正在尝试编译大学工作所需的代码库 以下是我已采取的步骤 我使用 Rosetta 将终端设置为始终打开 安装的自制程序using bin bash c curl fsSL https raw g
  • Task.WaitAll 保持循环

    我正在尝试这个异步代码只是为了测试 async 关键字 public async Task
  • 不明确的元函数或未定义的类型

    我是元功能的新手 我想编写一个函数 将复合类型中某种类型的所有匹配项替换为其他类型 在示例中 replace
  • 如何在MVVM架构中将animationview play与LottieForms绑定?

    所以我在列表视图中处理动画 并且我想随时播放一次 所以我想控制它 这是图书馆https github com martijn00 LottieXamarin https github com martijn00 LottieXamarin
  • Windows 消息

    我需要发送带有自定义 ID 的自定义 Windows 消息 其他应用程序将侦听该消息 Windows 是否为内部消息保留任何预定义的消息 ID 范围 如 SQL Server 那样 内部消息最多为 50 000 The 文档 https m
  • 包含不同类型的两个集合相交

    假设我有一个集合 称之为ids它是类型IEnumerable
  • 如何声明和定义具有推导类型的静态成员?

    我需要定义一个具有复杂 许多模板参数 类型的静态成员 不是 constexpr 因此 希望有这样的东西 struct X static auto x makeObjectWithComplexType 但它不是 C 所以我尝试解决它 并认为
  • 将引用托管代码中分配的内存的指针传递给非托管代码

    我在 C 中分配了一个大的 char 缓冲区 并且希望将指向此数据的指针传递给 DLL 中的未管理的 c 函数 现在我认为要使其工作 必须修复字符缓冲区 以便 GC 在函数工作时无法移动它 如果是这样 我会声明缓冲区已固定并调用 UNSAF
  • 如何从与桌面交互的应用程序与 Windows 服务进行通信?

    使用 Net 与服务交互的最佳方式是什么 即大多数托盘应用程序如何与其服务器通信 如果这个方法也是跨平台的 那就更好了 在 Mono 中工作 所以我猜远程处理已经过时了 Edit 忘了说了 我们仍然需要在现场支持 Windows 2000
  • gcc 编译器开关 (-mavx -mavx2 -mavx512f) 到底有什么作用?

    我在 C C 代码中明确使用了英特尔 SIMD 内在扩展 为了编译代码 我需要在命令行上指定 mavx mavx512 或类似的内容 我对这一切都很满意 然而 从阅读 gcc 手册页来看 并不清楚这些命令行标志是否也告诉 gcc 编译器尝试
  • Azure:MissingRegistrationForLocation:未在位置“YYYY”中为资源类型“XXXX”注册订阅

    这最初是作为未找到订阅 https stackoverflow com questions 35071797 subscriptionnotfound the subscription resourcegroups could not be
  • LINQ 表达式树 Any() 位于Where() 内

    我正在尝试生成以下 LINQ 查询 Query the database for all AdAccountAlerts that haven t had notifications sent out Then get the entity
  • 将 tiff 像素长宽比更改为正方形

    我正在尝试对多页 tiff 文件执行条形码识别 但是 tiff 文件是从传真服务器 我无法控制 发送给我的 该服务器以非方形像素长宽比保存 tiff 这导致图像由于纵横比而被严重挤压 我需要将 tiff 转换为方形像素长宽比 但不知道如何在
  • 缓存行对齐(需要文章澄清)

    我最近在我的应用程序中遇到了我认为是错误共享的问题 我查了一下关于如何将我的数据与缓存行对齐 他建议使用以下 C 代码 C using C 0x alignment syntax template
  • Oracle 的商业 Hotspot JVM 相对于 OpenJDK 有哪些性能优势?

    正如这个问题中所描述的 OpenJDK 与 Java HotspotVM https stackoverflow com q 44335605 1593077 Oracle 的商业 Hotspot JVM 本质上是 OpenJDK 加上一些
  • Phong 着色问题

    我正在根据以下内容编写着色器冯模型 http en wikipedia org wiki Phong reflection model 我正在尝试实现这个方程 其中 n 是法线 l 是光线方向 v 是相机方向 r 是光反射 维基百科文章中更
  • 为什么 typeof 函数在 C 中不起作用

    我使用GCC编译器 版本9 2 0 我想在 C 中使用 typeof 函数 但它会引发错误 错误 typeof 之前的预期表达式 如果您需要更多信息 请询问我 int a 5 double b the expected result is

随机推荐

  • 如何优化像素艺术编辑器中的绘制区域

    我有像素艺术创作程序 并且画布上有矩形 它们是一个字段 像素 对于数据量不大 例如 128x128 来说 这是一个很好的解决方案 如果我想在画布上创建 1024x1024 矩形 这个过程会很长 RAM 使用量约为 1 2 GB 之后程序运行
  • 带参数的累积正态分布函数的反函数

    我想在 C 中实现与 matlab icdf 函数等效的功能 我已经找到了这篇有用的文章 https www johndcook com blog cpp phi inverse https www johndcook com blog c
  • Pyspark AWS 凭证

    我正在尝试运行一个 PySpark 脚本 当我在本地计算机上运行它时 它可以正常工作 问题是我想从 S3 获取输入文件 无论我如何尝试 我似乎都无法找到设置 ID 和秘密的位置 我找到了一些有关特定文件的答案 前任 通过 Spark 或更好
  • 如何在 F# 中编写枚举而不显式分配数字文字?

    我在 F 中有一个枚举 如下所示 type Creature SmallCreature 0 MediumCreature 1 GiantCreature 2 HumongousCreature 3 CreatureOfNondescrip
  • 在 R 中将文本框保存为 pdf

    我正在尝试在 R 中创建项目符号类型列表 并希望将其保存为 pdf 格式 这成功地在窗口上打印了项目符号列表 a paste0 Starting portfolio value prettyNum 1000000 big mark scie
  • JPQL (JPA) 如果列表有交集则查找对象

    我有两个类 每个类都有一个标签列表 现在我想找到每一个对象ClassA包含列表中的任何项目ClassB 这可以用 JPQL 实现吗 或者使用单个查询 public class ClassA private List
  • 在 Qt 中解析 HTML 的最佳方法?

    在 Qt 中 我将如何解析充满 BAD html 的页面上的所有 a html 标签 href 属性 我会使用内置的 QtWebKit 不知道它的性能如何 但我认为它应该捕获所有 坏 HTML 就像是 class MyPageLoader
  • Unity:编辑器模式不支持 VRDevice 纸板。请在目标设备上运行

    卡板测试时存在屏幕无法分割的问题 我使用的 goolge sdk 版本为 unity 1 6 和 Unity 5 6 2f1 在模拟器 unity游戏场景 中 游戏场景在玩时不会分裂 控制台显示 编辑器模式不支持 VRDevice card
  • 如何动态加载和使用/调用 JavaScript 文件?

    我需要动态加载 JavaScript 文件 然后访问其内容 File test js test function var pub pub defult id 1 return pub 在这种情况下它有效 但我需要动态加载
  • 如何从 C# 连接到正在运行的 Outlook 实例 [重复]

    这个问题在这里已经有答案了 在VBA中 我通常使用appOutlook GetObject Outlook Application 获取正在运行的 Outlook 实例 如果 Outlook 未运行 则会引发错误 我通常在 Excel 中执
  • Android中的卡片翻转动画[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 I have tired to make a flip card in android Please make an image vi
  • 如何为 Owl Carousel 2 可见项目中的第一个和最后一个项目添加类?

    我需要向 Owl Carousel 2 上当前可见项目的第一个和最后一个项目添加一个类 DEMO http plnkr co edit t9URfKq9Mwh9jO705h7u p preview http plnkr co edit t9
  • 如何使用 16 或 24 列的 bootstrap

    我需要一些帮助将 bootstrap 2 0 4 设置为 16 或 24 列 而不是默认的 12 列 我无法理解我做错了什么我尝试了 bootstrap 站点上的自定义选项 并尝试更改变量中的网格变量 less 文件并使用 Crunch 重
  • 硒批判

    我只是想听听运行 Selenium 的人的一些意见 http selenium openqa org http selenium openqa org 我对 WaTiN 有很多经验 甚至还为它写了一个录音套件 我让它生成了一些结构良好的代码
  • 寻找 Lua 4.1 alpha

    我正在帮助为一款相当老的游戏 孤岛惊魂 开发多人模式 我想编译lua代码 但游戏使用版本4 1 alpha 我在任何地方都找不到 lua 4 1 alpha tar gz http www lua org work old lua 4 1
  • 适用于 Windows 的 Docker.io [已关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在读一个关于 docker 的好问题 答案概述了docker 实现细节 https stackoverflow com questio
  • ReSharper 忽略 TODO 资源管理器上的某些文件夹

    我在我的解决方案中使用 SignalR 他们的 Nuget 包引入了 java 脚本 没关系 但问题是 那里有待办事项 现在显示在我的待办事项列表下 因此 当 ReSharper 扫描 TODO 时 我想忽略特定文件夹或文件 我尝试从 代码
  • Attribute.IsDefined 看不到应用于 MetadataType 类的属性

    如果我通过以下方式将属性应用于分部类元数据类型属性 http msdn microsoft com en us library system componentmodel dataannotations metadatatypeattrib
  • Android 中失败 [INSTALL_FAILED_USER_RESTRICTED:无效的 apk]

    我使用的是Android Studio 3 0 1 当我尝试运行应用程序时 INSTALL FAILED USER RESTRICTED 无效的 apk 发生错误 我还禁用了即时运行 我再次运行应用程序 但出现同样的错误 04 04 10
  • Java 调用 GCC 编译的 C 库可以工作,但使用 G++ 编译时会失败

    我尝试调用这个最小的 C 代码 文件TEST c void Java TEST run 从这个Java代码 文件Example java public class Example public static void main String