Julia ccall outb - libc的问题

时间:2015-08-13 01:14:45

标签: julia glibc libc

我运行以下ccall

status = ccall((:ioperm, "libc"), Int32, (Uint, Uint, Int32), 0x378, 5, 1)
ccall((:outb, "libc"), Void, (Uint8, Uint16), 0x00, 0x378)

在第二个ccall之后,我收到以下错误消息:

ERROR: ccall: could not find function outb in library libc
 in anonymous at no file
 in include at ./boot.jl:245
 in include_from_node1 at loading.jl:128
 in process_options at ./client.jl:285

经过一番研究和搞乱后,我发现了以下信息:

  1. ioperm位于libc中,但outb不是
  2. 但是,iopermoutb都定义在同一个头文件中<sys/io.h>
  3. C代码的等效版本编译并顺利运行。
  4. glibc
  5. outb,但系统glibc 定义为 libc
  6. 完整路径名称/lib/x86_64-linux-gnu/libc.so.6
  7. 的问题相同

    修改

    感谢@Employed俄罗斯人的见解!我没有仔细观察extern声明。现在,我上面的所有笔记都很有意义!

    太棒了,我们发现ioperm是一个libc函数,在<sys/io.h>中声明,而outb不在libc中,但已定义在<sys/io.h>中作为易失性汇编指令。

    我应该使用哪个库或文件路径?

    ccall的实施。

1 个答案:

答案 0 :(得分:2)

  

但是,ioperm和outb都在同一个头文件<sys/io.h>

中定义

由&#34;定义&#34;你实际上是指&#34;宣布&#34;。它们是不同的。在我的系统上:

extern int ioperm (unsigned long int __from, unsigned long int __num,
                   int __turn_on) __attribute__ ((__nothrow__ , __leaf__));

static __inline void
outb (unsigned char __value, unsigned short int __port)
{
  __asm__ __volatile__ ("outb %b0,%w1": :"a" (__value), "Nd" (__port));
}

现在应该明白为什么你可以拨打ioperm而不是outb

更新1

  

我仍然不知道如何纠正错误。

您无法从outb导入libc。您必须提供自己的本地库,例如

void my_outb(unsigned char value, unsigned short port) {
  outb(value, port);
}

并从中导入my_outb。对于对称性,您应该以相同的方式实现my_ioperm,因此您要从同一本机库导入这两个函数。

更新2

  

让图书馆工作,但就性能而言,这太可怕了。

我想这就是为什么原始实现为内联函数的原因:你只执行一条outb指令,因此函数调用的开销很大。

  

未经优化的python可以更好地运行x5。

可能会将相同的outb指令内联到其中。

  

你知道outb是否存在于其他库中,而不是libc

那是会有所帮助:你仍然会有一个函数调用开销。我猜你从Julia调用导入的函数时,你可能会执行dlopendlsym调用,这会产生额外几百条指令的开销。

可能有一种方法来&#34;绑定&#34;该函数动态一次,然后重复使用它来进行调用(从而避免重复dlopendlsym)。 应该有所帮助。