Compiling a DLL using C - c

I am trying to compile a simple DLL using strictly C. The code for the entire test library is shown below:
#include <stdio.h>
__declspec(dllexport) void hello(void) {
printf("Hello, World!\n");
}
The library is meant to be a simple proof of concept which is built using CMake as provided by CLion with the following CMakeLists.txt:
cmake_minimum_required(VERSION 3.12)
project(test_lib C)
set(CMAKE_C_STANDARD 99)
add_library(test_lib SHARED library.c)
The DLL was built so I tried testing it with node-ffi and got Error: Dynamic Linking Error: Win32 error 126. Taking a step back from node-ffi, I put my newly created DLL in the apparently unanimously recommended debugging tool for DLLs: Dependency Walker. And it appears that the DLL I built has errors. Specifically:
Error: At least one required implicit or forwarded dependency was not found.
Warning: At least one delay-load dependency module was not found.
Dependency Walker did however find that I am exporting the symbol hello. I am basing this on the fact that hello is listed with an entry point when I examine the root DLL in Dependency Walker. It shows up in the bottom of the two right panes in Dependency Walker with nothing in the top most pane. The only item in Dependency Walker's bottom pane for symbol exploration looks something like:
E | Ordinal | Hint | Function | Entry Point
-----+------------+------------+----------+------------
[C ] | 1 (0x0001) | 0 (0x0000) | hello | 0x000010C8
Where the [C ] is a grayish color (if this means anything to anyone).
I am not sure what I am missing to cause this DLL to have faulty exported dependencies/symbols.

As it turns out, I was building for the wrong architecture. I was building for x86 with previous attempts (with my machine using an Intel processor). After all these attempts failing, I tried using this DLL in Python using ctypes. The error ctypes provided after loading in the DLL via CDLL('lib_test.dll') was much more elaborate, not only explaining the mismatched architecture, but which one my machine was expecting. In my case, it was x86-amd64.
Makes sense now that my DLL could not find those libraries. The DLL was attempting to fetch MSVC++ runtime libraries not installed since they are for a completely different architecture.

Related

Go compile returns duplicate symbols for architecture x86_64 error when I import 2 different packages which use C package via Cgo

Here is my code:
package main
import (
kusb "github.com/karalabe/usb"
tusb "github.com/trezor/trezord-go/usb"
)
func main() {
kusb.Enumerate(0, 0)
tusb.InitHIDAPI(nil)
}
When I compile (I'm using go mod to manage the packages), it returns this error:
duplicate symbol _libusb_dev_mem_alloc in:
/var/folders/fm/1rln65d94mn45s0h5l78tdyh0000gp/T/go-link-624554542/000002.o
/var/folders/fm/1rln65d94mn45s0h5l78tdyh0000gp/T/go-link-624554542/000020.o
ld: 136 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Why?
Some investigation i had:
The both packages use the same hidapi and libusb C packages in order to interact with usb devices.
Those C packages are identical, hence it defines the same functions so i think it is directly related to the error.
in trezord-go/usb, they include .C file, not the header file.
It is very counterintuitive to me because in the perspective of package users, I shouldn't need to worry about how a C package is used in the internal of the package, only the exposed types, functions and its behaviors.
Can anyone really explain what is going on here and how can I import both of them? They do different functions, eventhough they use the same C package.
From here: https://www.repustate.com/blog/go-duplicate-symbols-for-architecture-x86_64/
"What does this mean? Well, it means we're trying to link the same symbol name (in our case, a method) from two (or more) different source files. The fix was easy: rename one of the methods by updating the header file, the source file (.c or .cpp file) and lastly, updating your references to the symbol in your Go code, if it is directly referenced there."
Will it help ?
I was running into the same issue for hours and finally found the fix on a google groups channel
A package you import could be using cgo, you don't have to be using it directly
...
You can try CGO_ENABLED=0 go build and if it works then it is cgo related.
This was the charm that i was looking for! Hope this works for you too.

symbol lookup error: symbol exists, I know where it is, how do I get my SO to "see it"?

I am writing a plugin module for a larger program, written in C++. I have never written a SO library before. My module compiles and links correctly (I think) however the main program loading the SO crashes with the error symbol lookup error.
The module I am writing worked fine, until I started to try and use other libraries within it. (Specifically caffe)
There is a main program which is developed by another group
I am writing a plugin module for this program
My plugin module uses functions / code from Caffe (from the libcaffe.so file, Caffe itself is a compiled binary just to add to confusion)
The main program crashes with the following error
/path-to-binary/binary-name: symbol lookup error: ./build/libTestModule.so: undefined symbol: _ZN5caffe2db5GetDBERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
I tried adding export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib to my .bashrc.
I did this because (after some internet searching - I don't actually understand what I am doing here) I ran
nm -g libcaffe.so | grep _ZN5caffe2db5GetDBERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
in the folder /usr/lib and that symbol exists in libcaffe.so.
00000000001cbb30 T _ZN5caffe2db5GetDBERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
libcaffe.so is in /usr/lib and contains the symbol that my program cannot find.
My understanding is that (for some reason which is not known to me) I have to set LD_LIBRARY_PATH to /usr/lib so that my program can find libcaffe.co and the symbols contained within it.
However I would have assumed that since /usr/lib contains loads of "default" .so files, that this would be searched regardsless of whether LD_LIBRARY_PATH was set, ie shouldn't this directory be searched by default?
Regardless of the above question, I don't know what I should try next.
How can I get my program to find the symbol above in libcaffe.so?
CMakeLists.txt
cmake_minimum_required(VERSION 3.3)
project(TestModule)
find_package(Falaise REQUIRED)
add_library(TestModule SHARED TestModule.h TestModule.cpp)
set(Caffe_INCLUDE_DIRS "/usr/include/caffe")
set(Caffe_LIBRARIES "/usr/lib/libcaffe.so")
target_link_libraries(TestModule PUBLIC Falaise::FalaiseModule)
Your libTestModule.so is, you say, dependent on libcaffe.so but you are
not linking it. This:
cmake_minimum_required(VERSION 3.3)
project(TestModule)
find_package(Falaise REQUIRED)
add_library(TestModule SHARED TestModule.h TestModule.cpp)
target_link_libraries(TestModule PUBLIC Falaise::FalaiseModule caffe)
is how you would do so.

Biometric matching with futronic sdk using nodejs server

I have successfully taken bio-metric prints and posted to the node server using the futronic sdk. I want to be able to use this library likewise for matching in the server because that's where the bio-metric prints for all users are stored. I stubbled upon the node-ffi library that helps define equivalent C functions that I have exported and compiled it down to a .dll file.
Now the challenge here is that I have tried to port the ftrAnsiSDK functions but the ftrScanAPI.dll and the ftrAnsiSDK.dll file could not be compiled together. It gives this error:
...collect2.exe [Error] ld returned 5 exit status
When I compile and export the functions that are not dependent on these two libraries, my code works fine and the functions are easily exported and used in the node server. Please can any one give me a hint?
Here is the link to the repo. It consists of the lib and .dll library that is been used.
For the server code here is a snippet of what I am trying to achieve:
var libm = ffi.Library('lib/visystem', {
'HelloWorld': [ 'void', [] ],
'PrintErrorMessage': [ 'void', ['int'] ],
'CaprureImage': [ 'int', ['int','int','int'] ]});
The HelloWord and PrintErrorMessages are methods that I used as a test case to ensure the functions are being exported before I proceeded to the main functions (you can see the function definition in from the code in the repo.. ) that depends on the futronic lin and sdk.
I am currently using a 64-bit operation system and I installed the same program on a 32-bit machine to be sure, but it still did not compile and export the function. The code editor I am using is Dev++C.
Can anyone help or even give me hint on how to achieve this goal?
As a disclaimer, I'm not familiar with the Dev-C++ IDE or MinGW development.
However, after a cursory look at your github repo, according to your libvisystem.def file, it appears that the only functions that are exported by your DLL are:
HelloWorld
PrintErrorMessage
ReadTemplateFile
SaveBmpFile
SaveTemplateFile
This is also confirmed when looking at the libvisystem.a library header:
So you should probably start by manually add the rest of the exported functions in your dll.h to the def file, in a similar manner to the ones that are already there, and see if that changes anything.
NOTE:
I'm not sure whether the __declspec(dllexport) directive is ignored by the Dev-C++ compiler/linker and it uses the def file instead. Perhaps others on SO have an idea.

How to compile CHOLMOD library (SuiteSparse) from IDE

For some time I am trying to create a static CHOLMOD lib from SuiteSparse Each other library (f.ex. Umfpack) can be easiy compiled from IDE (I used Code::Blocks on Linux and Visual Studio on Windows). However when trying to compile CHOLMOD I get bunch of syntax errors like:
t_cholmod_triplet.c(21): error C2061: syntax error : identifier 'TEMPLATE'
I investigated that there are some #defines missing (like PATTERN, REAL defines) and therefore those definitions of TEMPLATE are invisible. I searched for them in files and in makefiles but found nothing. However when typing make (on Linux) library compiles just fine. What am I missing?
You can use SuiteSparse METIS for Windows package: https://github.com/jlblancoc/suitesparse-metis-for-windows
Credit: Jose Luis Blanco (Universidad de Almeria); Jerome Esnault (INRIA).
Actually the problem exists because of "templates" created in C. It requires to recompile the same code multiple times with different flags. I have written the VS NMakefile based on the original makegile and it compiled it seamlessly.

How to use C static libraries in D?

I'm completely stumped on how to get FreeType 2.4.8 compiled as a static lib and usable from within my D application in Windows. I've tried running it over with objconv, coff2omf, and trying extern(C)/extern(System), etc. but nothing seems to work. I'm getting symbol not found errors, access violations and just a bunch of unhelpful errors.
How can I work around this? Am I correct in using pragma lib to link to my static libraries, and how do I reliably convert COFF static libs to OMF which DMD/Optlink can use?
EDIT: Some examples of what I've tried doing:
Compiling the FreeType source with VS 2010 as a static lib, linking in my D code with pragma lib. (Returned a "library format unknown" type error)
Same as above, but converting to OMF format using objconv and then trying to link with pragma lib. (Linked successfully, but still not able to call functions.)
Compiled a DLL of the FreeType source, ran it through implib to create an import library, tried linking with pragma lib. (Linked successfully, but unable to to call any functions due to "attempt to privileged function" or "access violation" errors)
I've tried defining function prototypes as all of: extern(System), extern(C), and extern(Windows). The first and third mangle the functions names of the extern-ed functions such that they don't match the static libraries, and the second compiles, but I get access violations during runtime when I actually try and call the functions.
I'm able to get it working via dynamic libraries and symbol loading, but I'd much prefer to not require a bunch of external dependencies when deploying my project.
I'm pretty sure Derelict2 has FreeType bindings: http://www.dsource.org/projects/derelict (See DerelictFT).
Yes, you will need extern(System) in your .d files with FT function declarations.
Static library a collection of object files. So no need for any kind of conversion (omf2coff, etc). DMD accepts a static libraries as arguments, so simple dmd file1.d file2.d C:/path/to/freetype.lib should work.
Edit:
I was wrong. Apparently I needed to read some documentation about the COFF2OMF.
Quote: The Microsoft COFF format apparently changed with Visual C++ 6.0. To use coff2omf on a .lib file with the newer format, use Microsoft's linker to convert the file to the earlier COFF format:
link /lib /convert freetype.lib
So, judging by the statement above you need to perform 2 steps.
First use the Microsoft's linker to convert static library you made with the VisualStudio (in COFF format) to the old COFF format as described above.
Now execute coff2omf freetype.lib to convert the static library into the OMF format.
It should now be ready to be used with the DMD the way described originally in my post.

Resources