3

Is there a way to call go code from Microsoft Visual Studio C++?

Please Do Not close my question arbitrarily.

This link How to build a library with cgo using visual studio compiler? does not answer my question. It doesn't give a workable solution.

It seems cgo can only be compiled with mingw gcc at this time. https://github.com/golang/go/issues/49080#issuecomment-947865866

So, it seems this problem is unsolvable at this time.

Because mingw c header files are not completely the same as Windows SDK, there will always be some code that won't work.

This is like a "to be" or "not to be" problem.

If you want to call go code from c++, use mingw gcc to compile all your code.

you can't compile cgo with mingw and then use it in Visual Stdudio C++.(Maybe it will work, but there will always be some code that won't work)

All I can found is compile cgo with mingw gcc like this link https://gist.github.com/geraldstanje/4624ac47eb3dec5b8bbe12d4714ed330

But this method has a problem.

If you link the .a library with normal visual c++ code, it faied because .a library contains symbol that visual c++ doesn't know

clang -w *.cpp v2pn.a
LINK : warning LNK4217: symbol '__acrt_iob_func' defined in 'libucrt.lib(_file.obj)' is imported by 'v2pn.a(000005.o)' in function '_cgo_preinit_init'
LINK : warning LNK4286: symbol '__acrt_iob_func' defined in 'libucrt.lib(_file.obj)' is imported by 'v2pn.a(000006.o)'
LINK : warning LNK4217: symbol '_errno' defined in 'libucrt.lib(errno.obj)' is imported by 'v2pn.a(000005.o)' in function '_cgo_beginthread'
v2pn.a(000005.o) : error LNK2019: unresolved external symbol __imp__beginthread referenced in function _cgo_beginthread
v2pn.a(000005.o) : error LNK2019: unresolved external symbol __mingw_vfprintf referenced in function fprintf
v2pn.a(000006.o) : error LNK2001: unresolved external symbol __mingw_vfprintf
a.exe : fatal error LNK1120: 2 unresolved externals
clang: error: linker command failed with exit code 1120 (use -v to see invocation)

If you link the .a library with visual c++ code with mingw gcc,

Well, there will be much more problems. Because the mingw headers are not completely synchronous with windows SDK headers, there will be a lot errors.

Like this one

gcc.exe *.cpp v2pn.a
v2pn.cpp: In function 'void set_dns_by_guid(PCHAR)':
v2pn.cpp:48:5: error: 'DNS_INTERFACE_SETTINGS' was not declared in this scope
   48 |     DNS_INTERFACE_SETTINGS settings = {DNS_INTERFACE_SETTINGS_VERSION1};
      |     ^~~~~~~~~~~~~~~~~~~~~~
v2pn.cpp:49:5: error: 'settings' was not declared in this scope
   49 |     settings.Flags = 0x0002;
      |     ^~~~~~~~
v2pn.cpp:51:17: error: 'SetInterfaceDnsSettings' was not declared in this scope
   51 |     DWORD ret = SetInterfaceDnsSettings(interfaceGUID, &settings);
      |                 ^~~~~~~~~~~~~~~~~~~~~~~

This is because the mingw netioapi.h header file is different from the Windows SDK netioapi.h.

And the Windows SDK netioapi.h header file contains the DNS_INTERFACE_SETTINGS declaration, but the mingw netioapi.h header file doesn't.

Gary Allen
  • 385
  • 1
  • 3
  • 11

1 Answers1

0

Like you said cgo doesn't support MSVC C++ libraries to be linked. Even if you try to expose pure C-like API's and try to link mostly likely you will fall into the name mangling problem. One solution that will work is to write a C wrapper around the C++ APIs that needs to be exposed and use proper extern prefixes. This will get you out of the C++ name mangling problem and cgo does not differentiate which compiler a C library is compiled from.

As an example, API.cpp

class CppApi {
  int Run(int arg1);
}

CAPI.h

#ifdef API_EXPORTS
#define RUN_API __declspec(dllexport)
#else
#define RUN_API __declspec(dllimport)
#endif

#ifdef __cplusplus
extern "C" {
#endif
  RUN_API void* GetAPI();
  RUN_API int Run(void* obj, int arg1);
#ifdef __cplusplus
}
#endif

CAPI.cpp

void* GetAPI() {
  return (void*)(new CppApi());
}
int Run(void* obj, int arg1) {
  CppApi cppObj = CppApi*)obj;
  return cppObj->Run(arg1);
}

Note that this solution only works if you're willing to expose pure C functions without any C++ types or any Microsoft's types.

Niranjan M
  • 26
  • 4