1

I'm trying to implement a Julia Wrapper for a C API I'm using. For instance : I've got the following prototype :

int32 foo(int32 BrdType, int32 BrdNumber, Bd *pBrdHandle).

Base on the source code the definition of Bd is typedef void ***Bd; Bd will then be used later to manipulate my hardware (for instance with int32 otherfoo(Bd BrdHandle))


What I tried in julia

Currently, I can call my foo function in julia, but I'm not able to deference my pointer...

function fooWrap()
    #function Pointer
    lib = dlopen(find_library("foo.dll"))
    func = dlsym(lib, "foo")
    #Argument
    BrdType = -1
    BrdNumber = 0
    pBrdHandle = Ref{Ptr{Cvoid}}()
    #Output
    result = ccall(func, Cint, (Cint, Cint, Ptr{Cvoid}), BrdType, BrdNumber, pBrdHandle)
    println("result : ", result)
    BrdHandle = unsafe_load(pBrdHandle)
    return BrdHandle
end

(NB : the unsafe_load function gave me the following error :

ERROR: MethodError: no method matching unsafe_load(::Base.RefValue{Ptr{Nothing}})
Closest candidates are:
  unsafe_load(::Ptr) at pointer.jl:105
  unsafe_load(::Ptr, ::Integer) at pointer.jl:105

So how should I do to "transform" my pBrdHandle into BrdHandle ?

Thanks a lot for your help :)


EDIT

For clarity purpose, here are the "real" signature of the function :

BIRC BiBrdOpen(BFU32 BrdType, BFU32 BrdNumber, Bd *pBrdHandle)

BIRC BiBrdClose(Bd Board)

with typedef unsigned __int32 BFU32;, typedef BFU32 BFRC; and typedef void ***Bd;

Julie96
  • 331
  • 1
  • 15
  • 1
    `pBrdHandle = Ref{Ptr{Cvoid}}()` why do you need a reference to a pointer? you can just use a pointer I guess. – jling Aug 17 '21 at 14:27
  • I used [this question](https://stackoverflow.com/questions/40140699/the-proper-way-to-declare-c-void-pointers-in-julia) to make my declaration. Otherwise, I had an error when calling `ccall` – Julie96 Aug 17 '21 at 14:56
  • 1
    I see. try `unsafe_load(pBrdHandle[])` then? – jling Aug 17 '21 at 15:11
  • not working either... `print(pBrdHandle)` gave me `Base.RefValue{Ptr{Nothing}}(Ptr{Nothing} @0x0000000054548fe0` and `BrdHandle = unsafe_load(pBrdHandle[])` gave `BrdHandle::Nothing = nothing` – Julie96 Aug 17 '21 at 15:25
  • 1
    This question is hard to answer without actual signatures for the C functions. Are you sure that the signature for `int32 otherfoo(Bd BrdHandle)` is not `int32 otherfoo(Bd *BrdHandle)`, for example? It's pretty unusual for opaque handles to be passed as pointers in some functions and dereferenced in others. – StefanKarpinski Aug 17 '21 at 16:26
  • 1
    "the definition of Bd is typedef void ***Bd;" Great, so you get a `void****pBrdHandle`. The solution in this case is to toss this code in the garbage and rewrite it from scratch. Whoever wrote it was obviously completely incompetent - you cannot salvage this code. – Lundin Aug 18 '21 at 08:03
  • Unfortunately yes I'm sure that the signature is `int 32 otherfoo(Bd BrdHandle)` and unfortunately, the code is an API of a very specific hardware I cannot toss it (for now..) NB : I edited the Signature C functions for clarity. – Julie96 Aug 18 '21 at 08:26
  • But there's chance that the hardware is of the same non-existing quality as the software. When I google this I get hits on medical devices... if that's the case, then this library is literally criminal – Lundin Aug 18 '21 at 11:12
  • Actually, it is for a frame grabber – Julie96 Aug 18 '21 at 11:22
  • @Lundin : Could you briefly explain me why do you think this code is garbage ? (expecially the void **** part) – Julie96 Aug 18 '21 at 11:42
  • 1
    Summary: https://wiki.c2.com/?ThreeStarProgrammer Basically, people who write code as complicated as they possibly can are very bad programmers. The truly skilled programmers are those who write code as simple as possible. – Lundin Aug 18 '21 at 11:45
  • `Bd` is just a pointer to some opaque type. It would be clearer this way: `typedef struct Opaque *Bd;` – Zsigmond Lőrinczy Aug 19 '21 at 08:07

0 Answers0