【发布时间】:2021-05-22 22:37:39
【问题描述】:
假设我有 C 语言中的事件驱动 TCP 通信库。
在我的 Raku 应用程序中,我可以使用 NativeCall 调用 C 库中的函数。
my $server = create-server("127.0.0.1", 4000);
现在,从我在 C 中的回调 (say onAccept) 中,我想在我的应用程序中调用 Raku 函数(比如 on-accept(connection),其中 connection 将是指向 C 结构的指针)。
那么,我该怎么做:从我的 C 函数 onAccept 调用我的 Raku 函数 on-accept ?
ps。我尝试使用简单的标题“如何从 C 代码调用 Raku 代码”发布,但无论出于何种原因,stackoverflow.com 都不允许我这样做。因此,我编造了这个花哨的标题。
我正在创建一个 32 位 DLL。 我们必须明确告诉 CMake 配置 64 位构建。
cmake -G "Visual Studio 14 2015 Win64" ..
不管怎样,现在代码运行了,这并不是我真正要求的,因为回调仍在 C 中。
看来我要求的不太可能。
我尝试使用 Haakon 建议的方法,但恐怕我不明白它是如何工作的。
我在 Windows 中,不幸的是,即使我将它们放在 C:\Windows\System32 中,Raku 也找不到我的 dll。它找到“msvcrt”(C 运行时),但不是我的 dll。
dll 代码 (Visual Studio 2015)。
#include <stdio.h>
#define EXPORTED __declspec(dllexport)
typedef int (*proto)(const char*);
proto raku_callback;
extern EXPORTED void set_callback(proto);
extern EXPORTED void foo(void);
void set_callback(proto arg)
{
printf("In set_callback()..\n");
raku_callback = arg;
}
void foo(void)
{
printf("In foo()..\n");
int res = raku_callback("hello");
printf("Raku return value: %d\n", res);
}
Cmake 代码
CMAKE_MINIMUM_REQUIRED (VERSION 3.1)
add_library (my_c_dll SHARED my_c_dll.c)
乐代码。
use v6.d;
use NativeCall;
sub set_callback(&callback (Str --> int32))
is native("./my_c_dll"){ * }
sub foo()
is native("./my_c_dll"){ * }
sub callback(Str $str --> Int) {
say "Raku callback.. got string: {$str} from C";
return 32;
}
## sub _getch() returns int32 is native("msvcrt") {*};
## print "-> ";
## say "got ", _getch();
set_callback(&callback);
# foo();
当我跑步时
$ raku test-dll.raku
Cannot locate native library '(null)': error 0xc1
in method setup at D:\tools\raku\share\perl6\core\sources
\947BDAB9F96E0E5FCCB383124F923A6BF6F8D76B (NativeCall) line 298
in block set_callback at D:\tools\raku\share\perl6\core\sources
\947BDAB9F96E0E5FCCB383124F923A6BF6F8D76B (NativeCall) line 594
in block <unit> at test-dll.raku line 21
乐版本。
$ raku -v
This is Rakudo version 2020.05.1 built on MoarVM version 2020.05
implementing Raku 6.d.
【问题讨论】:
-
我没有沮丧,我很开明:) ...至于加载 dll 的错误,是我的错
-
对于更多的上下文,在 Lua 中,C 代码可以调用 Lua 代码,所以也许它也可以在 Raku 中做类似的事情......所以,这就是我发布这个问题的原因
-
根据维基百科,对于 Lua,“......编译字节码的解释器是用 ANSI C 编写的,Lua 有一个相对简单的 C API 可以将其嵌入到应用程序中。”因此,如果您发布的问题更接近 @raiph 建议的标题(即互操作性),那么很自然地假设 Lua/C 互操作性将比 Raku/C 互操作性更容易。
-
@jubilatious1 我提出了一个简单的问题,“是否可以从 C 中调用 Raku?”,就是这样......似乎不可能,我没关系,我不是沮丧,也不生气,这只是我想知道的事情
-
@zentrunix 用户 .@Yatin 已(imo 无助地)编辑了您的问题以删除您的评论,即读者应该看到您的答案。所以现在读者会看到 JJ 的答案是公认的答案,并得出我认为不恰当的结论。 JJ 说他不再坚持原来的答案,但指出他不能删除它(因为你已经接受了)。也许将接受的答案从 JJ 更改为您的答案是否有意义?也就是说,即使你的回答仍然让我觉得你的原始问题没有明确的解决方案。我的下一条评论将说明我的意思。
标签: raku