I am trying to run C++ code inside my go code. I figured out that I need -enable-cxx11 flag during compilation (because otherwise I get an error like here).
But somehow flags do not work:
/*
#cgo CPPFLAGS: -enable-cxx11
#include "cPackage/create_hyper_file_from_csv.cpp"
*/
import "C"
How do I use this flag?
Related
When I try to use import statements within C++20 with the modules feature under a Windows environment, I am not able to make it work because I must doing something wrong.
The key thing is that I tried different options on the cmd args without success (take any possible variation), like:
-fimplicit-modules -fbuiltin-module-map -fimplicit-module-maps
what relegates me to the use of the #include directives in the module purview, and it's provoking this kind of bug (related question Clang error including headers in C++ projects)
How does Clang should be instructed in order to find the modulemap that enables the usage of import statements for system headers under Windows (MSVC toolchain assumed).
Thanks.
I've been crash-learning Go (1.15.8) on Windows for the past two days, and I'm at the point where I need to call C (C++) from my Go program. I've scoured the Interewebs, but almost everything is for Linux--I'm on Windows.
Instead of monkeying with golang.org/x/sys/windows to try and wrap these calls, I've created a shared library that makes a number of pretty low-level Win32 API calls. It is compiled as C++, but it has a C interface that calls into the C++ function. This interface method has been wrapped in extern "C" to make it visible to Go. The header file has only this C interface function defined.
My cgo settings within the Go file look like:
// #cgo CFLAGS: -Imetadata
// #cgo LDFLAGS: -L. -lmetadata -lkernel32 -lole32
The shared library is called "metadata.dll". I compiled it with:
cl /c /EHsc /DUNICODE /D_UNICODE /Imetadata metadata/metadata.cpp
link /DLL /OUT:metadata.dll metadata.obj /MACHINE:X64 /INCREMENTAL:NO "kernel32.lib" "ole32.lib"
The library header looks like:
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
int metadata_comment(const char* filename, int is_dir, char* comment, int buffer_size);
#ifdef __cplusplus
} // extern "C"
#endif
When I try to build (or just run, for that matter), I get just:
# command-line-arguments
abnormal program termination
I tried using the -x flag to see if I could get more information, but there's really nothing happening there. As soon as it lists the env values, it dumps into the above message. Before aborting, my build line with the -x option looks like:
WORK=N:\Temp\go-build527705418
mkdir -p $WORK\b001\
cd M:\Projects\ls
TERM='dumb' CGO_LDFLAGS='"-g" "-O2" "-LM:\\Projects\\ls" "-lmetadata" "-lkernel32" "-lole32"' "D:\\Go\\pkg\\tool\\windows_amd64\\cgo.exe" -objdir "$WORK\\b001\\" -importpath command-line-arguments -- -I "$WORK\\b001\\" -g -O2 "-IM:\\Projects\\ls\\metadata" "M:\\Projects\\ls\\ls.go"
I've been using github.com/arrieta/golang-cpp-basic-example as a reference for this (but even there, he's using gcc and Linux).
Might this be a bug in this version of Go, or am I just doing something stupid? I was blazing along really well until I hit this brick wall. Any help or insights will be appreciated.
Visual Studio can debug DLL's - just tell it what command line is needed to start the executable which will load your DLL. That can be a Go executable; VS will know that it's just debugging metadata.dll. Since this is a native debugger, it will catch the crash as it happens.
Ok, this is straight from the horse's mouth:
Go uses and supports only mingw-w64 on windows, so you can only link
things that you can link with mingw and static libs created with msvc
isn't one of them. You can however dynamic link to msvc dlls.
So, what I have discovered is that, on Windows, (c)Go will not link directly to either a static or a dynamic library. Explicit MSVC support is something they are working on, but if you want to directly link to either kind of library, you currently have to use the mingw environment. He mentions that (c)Go will "link" to a dynamic library (i.e., DLL), but I could not get it to even do that.
However, what you can do is build your DLL with whatever lower-level accesses you need, and then load that DLL at runtime and access your visible function in your Go code. Here is some example Go code based on what I'm using now that completely solved my problem:
dll_metadata := windows.MustLoadDLL("metadata.dll")
proc_metadta := dll_metadata.MustFindProc("metadata_comment")
result := ""
const METADATA_BUFFER_SIZE = 1024
buffer := make([]byte, METADATA_BUFFER_SIZE)
var pBuffer *byte
pBuffer = &buffer[0]
len, _, _ := proc_metadata.Call(
uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(filename))),
uintptr(unsafe.Pointer(pBuffer)),
uintptr(METADATA_BUFFER_SIZE))
if len != 0 {
r := UTF16BytesToString(buffer)
result = r[:len]
}
I hope this helps others who might also be struggling with Go on Windows while trying to learn from the available examples which are virtually all based on some UN*X variant.
I'm new to make. I am working on a C++ shared library, and I want it to have the option to compile with or without support for a certain feature (block of code). In other words, how do I enable the user to choose whether or not to compile the library with that feature by (maybe) passing a parameter to the make command?
For example, I need the user to be able to do this:
make --with-feature-x
How do I do this? Do I need to write a configure file for example? Or can I do this directly within my Makefile?
I believe the following way should work. You define an environment variable when running make. In the Makefile, you check the status of the environment variable. Depending on the status, you define the options that will be passed to g++ when compiling the code. g++ Uses the options in the preprocessing phase to decide what to include in the file (e.g. source.cpp).
The command
make FEATURE=1
Makefile
ifeq ($(FEATURE), 1) #at this point, the makefile checks if FEATURE is enabled
OPTS = -DINCLUDE_FEATURE #variable passed to g++
endif
object:
g++ $(OPTS) source.cpp -o executable //OPTS may contain -DINCLUDE_FEATURE
source.cpp
#ifdef INCLUDE_FEATURE
#include feature.h
//functions that get compiled when feature is enabled
void FeatureFunction1() {
//blah
}
void FeatureFunction2() {
//blah
}
#endif
To check if FEATURE is passed in or not (as any value):
ifdef FEATURE
#do something based on it
else
# feature is not defined. Maybe set it to default value
FEATURE=0
endif
I try to embed Python in my C++ application, but the linker keeps saying this error:
[ILINK32 Error] Error: Unresolved external '_PyModule_Create2TraceRefs' referenced from E:\CPP PROJECTS\ANDERLICHT\WIN32\DEBUG\ANDERLICHT.OBJ
I'm using Embarcadero C++ Builder XE2, so I converted the python33.lib with coff2omf.exe.
This is my code in main.cpp:
#include "anderlicht.c"
#pragma comment(lib, "python33_omf.lib")
// In main():
PyImport_AppendInittab("anderlicht",PyInit_anderlicht);
Py_SetProgramName(programName.w_str());
Py_Initialize();
In anderlicht.c the Python.h is included. What do I have to do to fix this error?
I had the same problem, but I found a solution that doesn't need rebuild.
If you are developing a new application, you are in debug mode: the compiler defines _DEBUG. In the file "pyconfig.h" (near line 336 for python 3.6.3) you can find:
#ifdef _DEBUG
#define Py_DEBUG
#endif
=> Remove this code.
If you leave that code,you are in Py_Debug mode, so in object.h triggers this:
#if defined(Py_DEBUG) && !defined(Py_TRACE_REFS)
#define Py_TRACE_REFS
#endif
That in modsupport.h defines this alias:
#ifdef Py_TRACE_REFS
/* When we are tracing reference counts, rename module creation functions so
modules compiled with incompatible settings will generate a
link-time error. */
#define PyModule_Create2 PyModule_Create2TraceRefs
#define PyModule_FromDefAndSpec2 PyModule_FromDefAndSpec2TraceRefs
#endif
So your compiler needs a custom version of Python.
Now enjoy your standard embedded python.
The problem is most likely that you're using different compiler flags in building your code than were used in building the Python DLL. In particular, PyModule_Create2TraceRefs is only defined if you have -DPy_TRACE_REFS (which usually passed in via EXTRA_CFLAGS in the make command on Unix; I have no idea how you do it with Embarcadero C++ Builder on Windows). Usually, this isn't defined—in particular, if you're using a DLL from a pre-build Python binary, it won't have it defined.
So, if you want to have custom flags in building your code, you need to rebuild Python itself with the same flags. Otherwise, you need to get the flags that were used to build Python, and use the same ones when building your code.
On Unix, this is trivial: Just call python3.3-config --cflags and python3.3-config --ldflags to get the flags to pass to your compile and link steps. On Windows, it's less trivial. The Building C and C++ Extensions on Windows chapter in the docs explains how to do it when you're using the same toolchain used to build Python itself (usually MSVC), and if you're using mingw with its MSVC-compat features there's documentation elsewhere on how to do that… but if you're using a different toolchain, you will need to figure some of it out yourself.
How can I change the value of a boolean macro when I run my program through the command line? For instance, suppose I have the following macro in my cpp file, call it MyCpp.cpp
#define DEBUG 1
How can I change this when I run my program? through the command line:
g++ -Wall -Wextra -o MyCpp MyCpp.cpp
I am pretty sure you specify some kind of command line option, does this ring any bells?
Also, I do NOT want to use argv[]
First, change your source code:
#ifndef DEBUG
# define DEBUG 1
#endif
Now you can say on the command line:
g++ -Wall -Wextra -o MyCpp MyCpp.cpp -DDEBUG=5
# ^^^^^^^^^
The command line argument -DFOO=bar has the same effect as putting #define FOO bar in your source code; you need the #ifndef guard to avoid an illegal redefinition of the macro.
Sometimes people use an auxiliary macro to prevent the definition of another macro:
#ifndef SUPPRESS_FOO
# define FOO
#endif
// ... later
#ifdef FOO
// ...
#endif
Now say -DSUPPRESS_FOO to not define FOO in the code...
How can I change the value of a boolean macro when I run my program through the command line?
As it stands, you can't. You are using a preprocessor symbol so the decision as to whether debug information should be printed is a compile time decision. You are going to have to change that compile-time DEBUG symbol to a run-time variable that you set by parsing the command line, via some configuration file read in at run time, or both.
Parsing the command line isn't that hard. There are plenty of low-level C-style tools to help you do that. Boost has a much more powerful C++ based scheme. The trick then is to change those compile-time debug decisions to run-time decisions. At the simplest, it's not that hard: Just replace that DEBUG preprocessor symbol with a global variable. You can get quite a bit more sophisticated than this of course. Eventually you'll have a configurable logging system. Boost has that, too.
Please note the following. If you have in your c/cpp file or one of your included header files:
#define DEBUG 1
then you cannot modify this definition using the command line of the compiler (makefile). There is simply no chance. The cpp file will simply overwrite the command line setting.