I have been using cgo to interface between Go and C. However, when trying to do the same for Go and C++, I get a compile error every time I attempt to call a function. Using go build . from the code's directory, I get the following errors:
./main.go: In function 'void _cgo_3612c872201c_Cfunc_getint(void*)':
./main.go:48:53: error: invalid conversion from 'void*' to '_cgo_3612c872201c_Cfunc_getint(void*)::<anonymous struct>*' [-fpermissive]
./main.go:54:4: error: invalid conversion from 'void*' to '_cgo_3612c872201c_Cfunc_getint(void*)::<anonymous struct>*' [-fpermissive]
I've put a super simple example below which shows the problem.
main.go:
package main
/*
#cgo CFLAGS: -x c++
int getint()
{
return 1;
}
*/
import "C"
import (
"fmt"
)
func main() {
fmt.Println(C.getint())
}
Does anyone know if this is a bug in cgo, or something wrong with how I wrote the code? According to the cgo documentation, C++ is supported. I'm using Go version 1.7.5 for linux/amd64.
Thanks so much!
I may be wrong, but I think cgo supports C++ only in the sense it knows how to invoke a C++ compiler on the non-Go files which looks like containing C++ source code, and that's all.
The problem is that C++ compilers use so-called "mangling" for the symbols made exported from the compiled files. Exporting symbols were originally
intended only for C-like languages, where all which can be exported are plain
functions and variables, but C++ adds classes and function overloading,
and to export such symbols from compiled ("object") files, a C++ compiler
needs to "mangle" them using certain schema to encode names of classes
and types of arguments in these names. What's worse, each C++ compiler
brand uses its own mangling schemas.
So I think while cgo is able to compile C++ code, it sort of assumes that
all the symbols exported (to be used by Go) in your C++ files are
wrapped in extern "C" { ... } (see this).
If you need calls to "native" C++ exported stuff, you'd need to use
SWIG I reckon.
Related
I'm using CodeBlocks and GCC compiler. I'd like to use "string safe functions" e.g strlen_s, strcpy_s, but compiler shows an error:
Undefined reference to strlen_s.
I then add a line to the code:
#define __STDC_WANT_LIB_EXT1__ 1
As well as writing the following in the Compiler Options (settings -> compiler -> global compiler settings -> other compiler options):
-std=c11
In the book that I'm reading there's a code to checking whether my compiler supports these functions. The code is as follows:
#include <stdio.h>
int main()
{
#if defined __STDC_WANT_LIB_EXT1__
printf("optional functions are defined");
#else
printf("optional functions are not defined");
#endif
return 0;
}
When I run this code I see "optional functions are defined". I've also reinstalled CodeBlocks but I still get these errors.
Should I install another compiler? If I should, which one will be the best?
#define __STDC_WANT_LIB_EXT1__ 1 is expected to be defined by your application - you have to define it yourself to enable the use of the bounds-checking interface functions.
In order to see if the bounds-checking interface is at all available, you need to check if __STDC_LIB_EXT1__ is defined by the compiler.
Note that no function called strlen_s exists.
This test is not sufficient, you should also test whether the implementation defines the macro __STDC_LIB_EXT1__.
These functions are from a part of the C standard that is called "Annex K" and that is optional. With this macro you test if your C library provides that feature, with the WANT macro defined before any includes you tell the compiler that you want to use these features from Annex K.
Annex K is much controversial, and not many public domain C libraries implement it. Many people think that its interfaces don't provide the security that it claims.
And for the book that you are reading this doesn't seem to be too reliable. But then, I may be biased on that point.
I have a problem. Requirement for the project is that we cannot link our app with standard library ( so -nostdlib is on in gcc).
my_stdlib.c contains implementation of all functions my_memset, my_memcpy ... but linker needs memcpy to copy structs
MyStruct struct = my_struct;
and is complaining about "undefined reference to `memcpy'", which is of course correct.
Is it possible to remap memcpy to my_memcpy using linker script, parameters passed to ld or other way, so linker can use our implementation to copy structs?
Probably -wrap,function could help but I cannot change my_memcpy to __wrap_memcpy.
At the GCC level, you can redirect the memcpy symbol to a different symbol using:
void *memcpy (void *, const void *, size_t) __asm__ ("my_memcpy");
This will apply to internally-generated memcpy calls, too. (With GCC. I think it does not change the internal call sites with Clang.)
compile with -fno-builtin. This should avoid it.
I want to use my school custom library in a C++ project but the library linking seems not working... When I create my program in C and I try to compile it, it work...
See by yourself:
I think that the X11 and/or Xext libraries dependencies of the Mlx are in cause, there can be some
#if __cplusplus
void *x11_mlx_function_wanted(void);
#endif
I had already check if the mlx contains some check like that and I saw nothing.
Thank you in advance
EDIT
And I succeed in objective-c.
The problem is C++ name-mangling. If you declare a function in C11, it ends up with a "mangled" name, which encodes the namespace and the types of the arguments. That's necessary because in C++, various overloads can exist for the same function name. The overloads are independent functions; they do not even have to be in the same object library.
In the object library itself, the functions will have ordinary C names. But since the header file is processed with a C++ compiler, the declared functions will be named as though they were C++ functions.
One possible solution might be to declare all the included functions to be C functions:
extern "C" {
#include "/usr/X11/include/mlx.h"
}
I made a dll from my project and export a function using extern "C" like the code below:
main.cpp
extern "C" __declspec(dllexport) void __cdecl VectorOfMarker(char* InAdd,vector<NewMarker>& VectorMarkers)
{
DetectSeg d;
d.VectorOfMarker(InAdd,VectorMarkers);
}
I build the project and create the .dll and .lib files successfully.
then I create a new visual c++ project and try to use this dll and mentioned function in it.
Although I copied the .dll and .lib files to the same directory but I can't use extern "C" to import my function to the 2nd project. I think that I need to change some settings in visual studio 2010 to use the functions
Can anyone help me for this?
How can I use my exported function?
Too many thanks in advance
I think you are confused as to what type of the dll you are building.
There are two typed of the dynamitic linking implicit and explicit
.
To dynamically link a dll implicitly, you create dll that exports some functions and/or variables. This will create a DLL module and .lib import library. The module that is using this type of the dll, must have header file with function prototypes and must be linked with .lib import library.
So you are linking at the compile time. Since exports are done using __declspec(dllexport) and __declspec(dlleimport) and exported functions names are decorated (mangled). They look like ?ExportedTest##YAXPAD#Z.
Another type is explicit linking and that is most likely what you are doing.
Usually for this type of DLL function are exported using .def files to produce function names that are not decorated. This also can be achieved by using extern "C" modifier to tell C++ compiler to compile function as C style, hence exported function is not decorated and usre _ (underscore).
To use this type of the DLL you have todeclare function type and parameters, call Load library, and GetProcAddress to get function pointer. Then you will be able to make a call as follows:
typedef void (*DLLVectorOfMarker)(char*, vector<int>&);
HMODULE hMod = LoadLibrary(_T("ExportTest.dll")); // your lib name goes here
DLLVectorOfMarker pfnVectorOfMarker = (DLLVectorOfMarker)GetProcAddress(hMod, "VectorOfMarker");
vector <int> VectorMarkers;
pfnVectorOfMarker("some string", VectorMarkers);
I have written an DLL in Delphi which exports functions. I would like to use these functions in a C++ program without using dynamic Linking (LoadLibrary() API-Call).
The "import" declaration would be
extern "C" int __stdcall getVersionNumber();
I mainly use Bloodshed Dev-C++ which creates Windows Executables. But I do not know how to tell the compiler that it should import the function "getVersionNumber" from "STATMONDLL32.dll".
After I spent many hours by googling the problem, without any result (there was only weird stuff written about .a files and .lib files, which I do not have compiled by Delphi...) I have also installed VC++, but even there, I could not find a way to tell the compiler to use a specific DLL.
I have created a DEF file for this DLL - how can I tell Dev-C++ and/or VC++ to use it? (Dev-C++ prefered)
// Edit: Delphi is creating UNDECORATED symbols. The symbol is exactly "getVersionNumber".
I have created following DEF file with an alias for decoration:
LIBRARY STATMONDLL32
EXPORTS
getVersionNumberA = _getVersionNumberA#0
I have created a *.lib file with VC++ "lib.exe":
lib.exe /DEF:StatMonDll32.def /OUT:StatMonDll32.lib
I have included the lib in VC++ linker settings.
But VC++ tells me that it cannot resolve the external symbol _getVersionNumberA#0 ! Please help!
// Edit: I have uploaded the DLL here: http://www.viathinksoft.de/temp/StatMonDll32.dll . Can you access the symbol getVersionNumberA with VC++ ? I am searching for a solution since 6 days now :'-(
Best regards
Daniel Marschall
You can use dynamic linking, it should work something along the lines of:
extern "C" typedef int (__stdcall *pfnadd)(int a, int b);
extern "C" typedef int (__stdcall *pfngetversion)(void);
HMODULE mod = LoadLibraryA("mydll.dll");
pfnadd add = (pfnadd)GetProcAddress(mod, "Add");
pfngetversion getVersionNumberA =
(pfngetversion)GetProcAddress(mod, "getVersionNumberA");
and then you can just call using the function pointer:
add(1, 2);
std::cout << getVersionNumberA();
Although, it seems like your question has bits and pieces of two different functions!