On Windows, from a go code using CGO, I am calling a function from a cpp file.
The function (from the cpp file) calls _stprintf_s. When I comment call to this function, the go code builds fine.
But in presence of this call i get followin error
error: 'sprintf_s' was not declared in this scope
I have included the required <stdio.h> & <tchar.h> in cgo.
Not sure why _stprintf_s is producing this error. any help/pointers are welcome.
Related
I have some HDF5 C code that I am trying to port to C++Builder. I am getting this error at build time:
[ilink64 Error] Error: Unresolved external 'H5check_version' referenced from D:\DELPHITOOLS\PASHDF\C\WIN64\DEBUG\FILE2.O
H5check_version is included in H5public.h as a macro.
Why does C++Builder not find this?
H5check_version is included in H5public.h as a macro.
If that were true, you would not be getting a linker error, since macros are handled only during the preprocessor stage.
Somewhere in your project, the compiler is seeing a declaration of H5check_version as a function, and your file2 unit is calling it as a function, but the linker can't find the implementation of that function, hence the error.
Your project needs to contain a reference to the appropriate .lib file that either implements the actual function (static linking) or tells the linker which DLL the function is exported from (dynamic linking).
C/C++ is case sensitive, so H5check_version is different from H5Check_version.
AFAIK pascal is not case sensitive at all.
Regards
I want to create a shared library, using Go, to be used by a third-party software (STAR-CCM+). That software provides some utility c functions for my code to call, and expects my code to, at a minimum, define a specific function, which the third-party software will call after loading the library.
My problem is Go complains about undefined references for the utility functions:
/tmp/go-build672782048/b001/_x002.o: In function `_cgo_c4b84da031f3_Cfunc_utility':
/tmp/go-build/cgo-gcc-prolog:50: undefined reference to `utility'
How can I compile a shared library that calls a c function that is declared but not defined by my code?
The third-party software provides a header file similar to this:
uclib.h
#ifndef UCLIB_H
#define UCLIB_H
// utility function defined by third party software, declared here
extern void utility(int);
// function expected to exist in .so and defined by user
// this function is expected to call `utility` one or more times
void user_function();
#endif
Working example, c only
To test the interaction with the third party software, I build an example using only c:
usingc.c
#include "uclib.h"
void
user_function()
{
utility(1);
}
Build:
$ gcc -fPIC -c usingc.c -o usingc.o
$ gcc -shared -o libmine.so usingc.o
This results in a libmine.so that the third party software successfully loads and registers its utility function being called with 1. Note that utility was only declared, never defined, by my code.
Problematic example, Go
I create a simple go module with the header above and two files:
go.mod
module example.com/cgo_mwe
go 1.15
usinggo.go
package main
// #include "uclib.h"
import "C"
//export user_function
func user_function() {
C.utility(C.int(2))
}
func main() {}
I attempt to build the shared library and observe the error:
$ go build -o libmineg.so -buildmode=c-shared
# example.com/cgo_mwe
/tmp/go-build672782048/b001/_x002.o: In function `_cgo_c4b84da031f3_Cfunc_utility':
/tmp/go-build/cgo-gcc-prolog:50: undefined reference to `utility'
collect2: error: ld returned 1 exit status
The are three possible solutions to allow the linking with the undefined reference. The second two are found in the golang-nuts Google Group:
ignore all undefined references via LDFLAGS with -shared
// #include "uclib.h"
// #cgo LDFLAGS: -shared
import "C"
ignore all undefined references via LDFLAGS with -Wl,-unresolved-symbols=ignore-all:
// #include "uclib.h"
// #cgo LDFLAGS: -Wl,-unresolved-symbols=ignore-all
import "C"
mark the declared but undefined functions as weak in the header file:
#pragma weak utility
// utility function defined by third party software, declared here
extern void utility(int);
The advantage of #3 is that references not marked weak are still called out as undefined.
My codes and the errors that I got
I got this problem with the turbo c++ that every time I'm compiling my codes it just pull some errors which I already tested to online compiler (gdb online compiler).
The first error is "Declaration is not allowed here".
The file is .C, not .CPP, so it is probably compiled as C and not as C++. Variable definitions in the middle of the code are only allowed in C++. Just move the definition to the beginning of the function.
The following warnings are "Function should return a value".
If a function is not defined as void (eg. int) it should have a return statement which returns a value of the type of the function.
I'v been trying to get OmniThreadLibrary to run in builder, i've built it with all the c++ required files it builds ok but when i use it in an c++ builder app i get a bunch of error messages that look like the following
[bcc32 Error] DSiWin32.hpp(385): E2040 Declaration terminated incorrectly
one points at this line of code in the generated hpp file
static const System::Int8 CSIDL_ADMINTOOLS = System::Int8(0x30);
has anyone had this working in C++ builder or know the best way to resolve these issues
I'm using c++ builder settle and OmniThreadLibrary version 3.06
The Win32 API (and Delphi, for that matter) already declares CSIDL_ADMINTOOLS, Omni should not be declaring it at all. It should be using Delphi's Shlobj unit instead.
The Win32 API declares CSIDL_ADMINTOOLS using a #define statement:
#define CSIDL_ADMINTOOLS 0x0030
So the declaration in Omni's .hpp is getting modified by the C++ preprocessor to this:
static const System::Int8 0x0030 = System::Int8(0x30);
Thus the "Declaration terminated incorrectly" compiler error.
When Delphi code declares something that already exists in C++, it needs to be declared as either {$EXTERNALSYM} or {$NODECLARE} to avoid duplicate declarations, and then optionally use {$HPPEMIT} to output a relevant #include statement in a generated .hpp file. Delphi's units already do that for its Win32 declarations.
If Omni is not already doing that (and the error would suggest it is not) then it needs to be updated accordingly.
I tried building the first example here and got errors. Right on the first line there's a missing include statement, but I managed to figure out it should be
#include "hdf5.h"
But even after fixing that I got more errors:
$ h5cc ./example1.c
./example1.c: In function ‘main’:
./example1.c:66:4: error: too few arguments to function ‘H5Dcreate2’
In file included from /usr/include/hdf5.h:27:0,
from ./example1.c:6:
/usr/include/H5Dpublic.h:104:14: note: declared here
Any idea how to solve it?
The example code was written for release 1.6 of hdf5, and as such will simply not compile on a 1.8 release without modification.
If you want to get the code to work on 1.8, you need to enable 1.6 compatibility, which means passing in the flag:
-DH5_USE_16_API
to the h5cc command line like:
h5cc -DH5_USE_16_API ./example1.c
and it should compile correctly; otherwise you will have to rewrite the code to make use of the 1.8 API.