Search code examples
godllcgo

CGo tests with a DLL


I'm currently using CGO to use a library in C through a DLL. Everything works and I can use my code on top of the library, build it & so on.

The problem I have is to implement tests with a DLL. Right now my project looks like:

  • project
    • apis/
      • probes.go
      • probes_test.go <- uses Struct containing C defs
    • lib/
      • binding.go <- defines CGO binding
    • main.go
    • myLib.dll

So my lib folder got all CGO binding and a Go struct on top of it (as a wrapper kind of). And the probes are using this wrapper to expose some infos.

The problem with doing go test is that the execution context is set within the package. Meaning probes_test.go executes in apis/ context and doesn't see the DLL. Making the test fail with a special exit status.

The workaround is to replicate for now the dll in the package like:

  • project
    • apis/
      • probes.go
      • probes_test.go
      • myLib.dll <- replicated
    • lib/
      • binding.go
    • main.go
    • myLib.dll

And this works (the test passes) but is hacky and not clean. I also tried to put the DLL only in lib/ but isn't working neither.

Do you have a way of specifying for test that the DLL is in an other folder ?


Solution

  • If you need DLLs from other paths to be accessed during execution time, you have to increase the search path range by adding additional directories to the PATH environment variable:

    SET PATH=<MY_LIB_DLL_DIR>;%PATH%
    

    In this way the DLL is found regardless from where you execute the program.

    A recommended practice for testing in relocatable environments (checking out on different systems in different directories) is to open a console with a batch file which sets the environment you need for building.

    echo off
    :: ensure current dir is in directory of batchfile location
    cd /D %~dp0 
    :: TODO replace dll_dir below your dll directory
    pushd %dll_dir%
    :: set path
    set PATH=%CD%;%PATH%
    popd
    :: open console here
    cmd /k
    

    put this batchfile in the root of your project to open a working console from there