gpt4 book ai didi

raku - 从 C 代码调用 Raku 代码的协议(protocol)是什么?

转载 作者:行者123 更新时间:2023-12-04 11:17:57 25 4
gpt4 key购买 nike

假设我在 C 中有我的事件驱动的 TCP 通信库。
在我的 Raku 应用程序中,我可以使用 NativeCall 调用 C 库中的函数。

my $server = create-server("127.0.0.1", 4000);
现在,从我在 C 中的回调( say onAccept )我想调用我的应用程序中的 Raku 函数(比如 on-accept(connection) 其中 connection 将是一个指向 C 结构的指针)。
那么,我该怎么做:调用我的 Raku 函数 on-accept来自我的 C 函数 onAccept ?
附:我尝试使用一个简单的标题“如何从 C 代码调用 Raku 代码”进行发布,但无论出于何种原因,stackoverflow.com 都不允许我这样做。正因为如此,我编造了这个花哨的标题。
我正在创建一个 32 位 DLL。
我们必须明确告诉 CMake 配置 64 位构建。
cmake -G "Visual Studio 14 2015 Win64" ..
无论如何,现在代码运行了,这并不是我所要求的,因为回调仍然是在 C 中。
我所要求的似乎不太可能。
我尝试使用 Haakon 建议的方法,但恐怕我不明白它是如何工作的。
我在 Windows 中,不幸的是,Raku 找不到我的 dll,即使我将它们放在 C:\Windows\System32 中。它找到“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.

最佳答案

另一种方法可能是在 C 库中静态保存回调,例如 ( libmylib.c ):

#include <stdio.h>

static int (*raku_callback)(char *arg);

void set_callback(int (*callback)(char * arg)) {
printf("In set_callback()..\n");
raku_callback = callback;
}

void foo() {
printf("In foo()..\n");
int res = raku_callback("hello");
printf("Raku return value: %d\n", res);
}
然后从乐:
use v6;
use NativeCall;

sub set_callback(&callback (Str --> int32)) is native('./libmylib.so') { * }
sub foo() is native('./libmylib.so') { * }

sub callback(Str $str --> Int) {
say "Raku callback.. got string: {$str} from C";
return 32;
}

set_callback(&callback);
foo();
输出 :
In set_callback()..
In foo()..
Raku callback.. got string: hello from C
Raku return value: 32

关于raku - 从 C 代码调用 Raku 代码的协议(protocol)是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66286010/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com