julia debug C代码


#1

C语言函数已经编译成dll, 在Julia中调用时返回值异常,请问如何才能调试C函数呢?


#2

1 启动Visual Studio,打开你的C语言项目,使用Debug配置把DLL编译出来
2 启动Julia
3 菜单栏/调试/附加到进程,选择Julia进程,“附加到”选择“本机代码”(Native Code),点击“附加”
4 给你的函数加断点
5 用Julia调用你的函数
6 命中断点,调试


#3

木有VS,只有VS code。请问gdb可以吗?


#4

理论上是个调试器都可以。但是你既然用Windows,为什么不用VS?最稳妥且Windows上最好的调试器


#5

平时用R语言,不做VS开发,20G的VS鸡肋


#6

如果是自己写的代码,你也可以干脆用纯Julia写


#7

年代久远的fortran代码, nlminb optimization,重写不可能。
https://github.com/kongdd/nlminb/blob/master/src/port.c

有个问题想请教,我怀疑也是出bug的原因。在julia中,我尝试调用的是这个函数nlminb_iterate,请问如何从julia中传递一个空数组到C double h[]呢?
https://github.com/kongdd/nlminb/blob/master/src/port.c#L340


#8

没有空数组一说,你的参数要求一个double* val,实际需要传入一个预先分配好的N个元素的double数组。如果这个函数需要写入缓冲区,你可以分配未初始化的数组,例如buf=Array{Float64}(undef,N)

julia> function c_iterate(p::Ptr{Float64},n::Int)
           for i=1:n
               unsafe_load(p,i)|>println
           end
           nothing
       end
c_iterate (generic function with 1 method)

julia> pfn=@cfunction(c_iterate,Nothing,(Ptr{Float64},Int))
Ptr{Nothing} @0x0000000128dc9da0

julia> arr=Float64[1,1,4,5,1,4]
6-element Array{Float64,1}:
 1.0
 1.0
 4.0
 5.0
 1.0
 4.0

julia> ccall(pfn,Nothing,(Ptr{Float64},Int),arr,length(arr))
1.0
1.0
4.0
5.0
1.0
4.0


#9

您说的是其中一种情况,以参数b为例,它的意义是参数的限制条件,可以提供也可以不提供。
提供时是长度为n的数组,不提供时是空数组。
C里面通过if (b) 判断 b是否为空。这种情况julia能够应付吗?


#10

问题完美解决了。

  • 如果需要传入空数组,需要设置b = C_NULL。
  • gdb调试c,在linux或mac下,
    # 可以独立运行的jl file, C function在 jl file中调用
    $ gdb --args julia nlminb_iterate.jl
    
    # breakpoint function name
    (gdb) b nlminb_iterate
    
    # 显示所有的参数
    (gdb) info args
    
    # 显示数组值, *代表取值,@2代表前2个元素
    (gdb) print *b@2
    

至此,错误信息就一目了然了。


#11

即便是空数组,也是具有有效的内存地址(首元素偏移)的。
isempty(b) ? C_NULL : pointer(b)

另外你可能需要这个 [在Windows下编写C/C++ DLL与Julia调用的正确姿势]


#12

谢谢。我用的Rtools下的gcc+fortran编译的