如何在 Windows 上编译共享库,以便可以与 raku 中的 NativeCall 一起使用?

2023-12-29

我正在尝试在 Windows 上编译一个 DLL 库,可以与本地调用 https://docs.raku.org/language/nativecall在乐。这是一个最小的 C 代码(my_c_dll.c):

#include <stdio.h>
#define EXPORTED __declspec(dllexport)
extern __declspec(dllexport) void foo();

void foo()
{
  printf("Hello from C\n");
}

我使用的是 Windows 10 并且已安装Visual Studio 2019 构建工具 https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2019。为了编译 DLL,我打开“VS 2019 的开发人员命令提示符”并运行:

> cl.exe /c my_c_dll.c
> link /DLL /OUT:my_c_dll.dll my_c_dll.obj

这会创建一个 DLLmy_c_dll.dll,然后我尝试使用 Raku 中的这个(test-dll.raku):

use v6.d;
use NativeCall;
sub foo() is native("./my_c_dll.dll"){ * }
foo();

但是当我运行这个(我已经安装了 Rakudo 版本 2020.05.1)时,我得到:

> raku test-dll.raku
Cannot locate native library '(null)': error 0xc1
  in method setup at C:\rakudo\share\perl6\core\sources\947BDAB9F96E0E5FCCB383124F923A6BF6F8D76B (NativeCall) line 298
  in block foo at C:\rakudo\share\perl6\core\sources\947BDAB9F96E0E5FCCB383124F923A6BF6F8D76B (NativeCall) line 594
  in block <unit> at test-dll.raku line 9

这里可能有什么问题?


无法找到本机库“(null)”:错误 0xc1

错误代码0xc1 is a Windows系统错误代码 https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499- :

ERROR_BAD_EXE_FORMAT
193 (0xC1)
%1 is not a valid Win32 application.

通过使用检查 DLL 的标头dumpbin https://learn.microsoft.com/en-us/cpp/build/reference/dumpbin-reference?view=msvc-160

> dumpbin /headers my_c_dll.dll
Microsoft (R) COFF/PE Dumper Version 14.26.28806.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file my_c_dll.dll

PE signature found

File Type: DLL

FILE HEADER VALUES
             14C machine (x86)
               4 number of sections
        6043A8CB time date stamp Sat Mar  6 17:07:39 2021
               0 file pointer to symbol table
               0 number of symbols
              E0 size of optional header
            2102 characteristics
                   Executable
                   32 bit word machine
                   DLL

我观察到它说machine (x86) and 32 bit word machine,所以我怀疑该DLL是32位DLL。但是,我在 64 位机器上:

> PowerShell -Command "systeminfo | perl -nE 'say if /System Type/'"
System Type:               x64-based PC

事实证明,Build Tools for Visual Studio 2019除了“VS 2019 的开发者命令提示符”之外,还安装了一些更多的开发者提示符,即:

  • VS 2019 的 x64 本机工具命令提示符
  • VS 2019 的 x64_x86 交叉工具命令提示符
  • VS 2019 的 x86 本机工具命令提示符
  • VS 2019 的 x86_x64 交叉工具命令提示符

通过打开“VS 2019 的 x64 Native Tools 命令提示符”并在此处重新编译 DLL,我现在得到:

> dumpbin /headers my_c_dll.dll
Microsoft (R) COFF/PE Dumper Version 14.26.28806.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file my_c_dll.dll

PE signature found

File Type: DLL

FILE HEADER VALUES
            8664 machine (x64)
               6 number of sections
        6043AAA2 time date stamp Sat Mar  6 17:15:30 2021
               0 file pointer to symbol table
               0 number of symbols
              F0 size of optional header
            2022 characteristics
                   Executable
                   Application can handle large (>2GB) addresses
                   DLL

请注意,输出现在显示machine (x64) and Application can handle large (>2GB) addresses,这似乎也解决了这个问题:

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

如何在 Windows 上编译共享库,以便可以与 raku 中的 NativeCall 一起使用? 的相关文章

  • uri 警告中缺少端口:使用 Python OpenCV cv2.VideoCapture() 打开文件时出错

    当我尝试流式传输 ipcam 时 出现了如下所示的错误 tcp 000000000048c640 uri 中缺少端口 警告 打开文件时出错 build opencv modules videoio src cap ffmpeg impl h
  • 使用taskkill停止Windows服务

    我需要帮助来使用 C 终止 Windows 服务 现在要终止该服务 请使用以下选项 从命令 sc queryex ServiceName 发现后PID服务的 taskkill pid 1234 exemple f 为了便于阅读 但如果您明白
  • MinGW Make 抛出“系统找不到指定的路径。”错误

    我正在尝试在 Windows 7 上使用 cmake 生成一个 c 项目 在实际创建项目之前 cmake 会对您的工具链进行快速测试 我正在使用 MinGW 这就是我的问题所在 Cmake 触发 make 构建 最终失败并返回 系统找不到指
  • 将 gnuplot 嵌入现有 QtWidget 中

    我正在用 C 创建一个 伪 实时绘图应用程序 使用 gnuplot 作为绘图后端 我的要求之一是绘图必须位于现有窗口内 而不是有一个单独的绘图窗口 gnuplot 默认为 Gnuplot 有一个选项可以指定 Qt 小部件 ID 这似乎适合我
  • 批处理脚本 FOR 循环仅设置输出的第一个字母 wsl --list -q

    我正在编写一个批处理脚本 将文件从 Windows 目录复制到 WSL 发行版 其中一部分是选择将文件复制到哪个发行版 如果我使用命令wsl list q如果给我以下输出 Ubuntu 22 04 Ubuntu 18 04 我正在尝试使用此
  • 从 Python 下载/安装 Windows 更新

    我正在编写一个脚本来自动安装 Windows 更新 我可以将其部署在多台计算机上 这样我就不必担心手动更新它们 我想用 Python 编写这个 但找不到任何关于如何完成此操作的信息 我需要知道如何搜索更新 下载更新并从 python 脚本安
  • Delphi中使用FindVCLWindow调用WinHelp32(WinXP Pro SP3 32bit)

    有什么问题吗 procedure TForm1 VCLHelpClick Sender TObject var Ctrl TWinControl begin Ctrl FindVCLWindow Mouse CursorPos if Ctr
  • Rails Windows Vagrant 响应时间非常慢

    我在跑 Vagrant 1 7 1 Rails 4 1 4 Thin 1 6 1 Windows 7 每个静态文件的发送时间都超过一秒 在我的 PC 上加载一个页面可能需要大约 20 秒 而在同事的 Linux 机器上则只需瞬间 有一些帖子
  • 如何创建向后兼容 Windows 7 的缩放和尺寸更改每显示器 DPI 感知应用程序?

    我是 WPF 和 DPI 感知 API 的新手 正在编写一个在 Windows 7 8 1 和 10 中运行的应用程序 我使用具有不同每个显示器 DPI 设置的多个显示器 并且有兴趣将我的应用程序制作为跨桌面配置尽可能兼容 我已经知道可以将
  • 什么是WINVER?

    我正在查看一些代码 他们有这一行 define WINVER 0x0501 in stdafx h文件 为什么需要定义WINVER 它如何影响您的代码 有人可以解释一下吗 WINVER 确定构建应用程序所需的最低平台 SDK 这反过来又会在
  • LNK2028 托管 C++ DLL 在另一个托管 C++ DLL 中调用函数

    我正在将 VS2010 与托管 C DLL 一起使用 调用另一个托管 C DLL 中的函数 并且我得到了很多LNK2028 http msdn microsoft com en us library ms235590 28v vs 80 2
  • 所有平台上的java

    如果您想用 java 为 Windows Mac 和 Linux 编写桌面应用程序 那么所有这些代码都相同吗 您只需更改 GUI 即可使 Windows 应用程序更像 Windows 等等 如果不深入细节 它是如何工作的 Java 的卖点之
  • Windows 上的递归移动命令

    我需要做一个 sh 的 bat 副本 我不太了解 Windows cmd 在 Linux 上我可以做 mv or rsync a SOURCE DEST remove sent files ignore existing whole fil
  • 在高 dpi Windows 平台上自动重新缩放应用程序?

    我正在编写一个需要在高 dpi Windows 192dpi 而不是 96dpi 上运行的 Qt 应用程序 不幸的是 Qt 框架尚不支持高 dpi 至少在 Windows 上 因此我的应用程序及其所有元素看起来只有应有尺寸的一半 有没有办法
  • Git difftool 未启动外部 DiffMerge 程序

    我一直遵循 戴夫的博客条目 http www davesquared net 2009 05 setting up git difftool on windows html 链接在此answer https stackoverflow co
  • Windows 上的 ffmpeg-android ndk

    我正在尝试编译 bash 文件 带有 android ndk 的 ffmpeg 我收到如下错误 arm linux androideabi gcc 无法创建可执行文件 C 编译器测试失败 Makefile 2 config mak 没有这样
  • Windows 上的 Apache Pig 在运行“pig -x local”时出现“hadoop-config.cmd”未被识别为内部或外部命令”错误

    如果您由于以下错误而无法在 Windows 上运行 Apache Pig hadoop 2 4 0 bin hadoop config cmd is not recognized as an internal or external com
  • 什么是 SO_SNDBUF 和 SO_RCVBUF

    你能解释一下到底是什么吗SO SNDBUF and SO RCVBUF选项 好的 出于某种原因 操作系统缓冲传出 传入数据 但我想澄清这个主题 他们的角色 通 常 是什么 它们是每个套接字的缓冲区吗 传输层的缓冲区 例如 TCP 缓冲区 和
  • 在 Windows 上查找父进程 ID

    Problem 给定远程 Windows 主机上的进程 ID 和命令行访问权限 如何找到其父进程的 PID Solution 鉴于 Marc B 的回答 我们可以使用 WMIC 命令示例here https learn microsoft
  • 从其可执行文件的路径获取服务名称

    我有一个可执行文件的路径 它是一个正在运行的服务应用程序 例如 C Program Files x86 Someapp somesvc exe 我想停止并启动它 为此我想我需要获取服务的名称 如下所示 this https stackove

随机推荐