Call C++ from C#

Hi all,

I am implementing a C++ dll into my C# application. My knowledge of C++ is very basic so I don't know how to translate some structs and events.

The biggest problem I have right now is how to hook up events. C++ needs the following struct as input on a method:

typedef struct
  HWND parent;
... (others)
  EXT_FUNCTIONS  externalFunctions;

  void (__stdcall *fFirstCaller)        (void *pVoidExternal, int Parms);
  void (__stdcall *fSecondCaller)    (void *pVoidExternal);

typedef struct EXT_FUNCTIONS_TYPE
  int    (__stdcall *FirstEvent)    (void* pVoidExternal);
  void  (__stdcall *Executing)     (void* lpVoid1, int Parm1, int Parm2, unsigned char *szParm3);

Open in new window

I a using DLLImport to load the DLL into memory in C# and use "external static" to get a reference to the functions.
If I understand correct both above structs also need eventhandler. How must I translate and use the structs in C#?

Please supply examples.
LVL 12
Who is Participating?
It is much easier to work with native C++ if you use C++/CLI because of several things the compiler would do for interoperability.

If I had to do it, I would create a simple C++/CLI wrapper class usable from managed code and delegating stuff to native API.

But even if using C#, delegates can be passed to native methods expecting callbacks. Heres an example:
I am sorry, but if a native code DLL requires callback function pointers, you won't be able to supply them from managed code for it's sheer nature. They have to be be implemented in native code as well.
rovermAuthor Commented:
What do you mean?
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

There is no such thing as function pointers in managed code. Therefore, you will have to wrap another layere of native code around the DLL you want to use and call that layer from C#. Function pointers are direct offsets into native assembly code (OK, that's a bit simplified, yet on the head), that's why they have no counterparts in the managed world.
As an example, see the following C++/CLI snippet from a real project with native and managed code mixed.

IComponentHost^ SomeComponentHostFactory::CreateComponentHost(List<KeyValue^>^ config)
	auto dictionary = ConfigHelper::ToDictionary(config);
	ConfigHelper::Require(dictionary, L"BaseFolder");
	ConfigHelper::Require(dictionary, L"Arguments");

	std::auto_ptr<Native::SomeComponentHostConfig> cfg = new Native::SomeComponentHostConfig();

	cfg->friendlyName = "SomeComponent";
	cfg->workingDir = marshal_as<std::string>( dictionary[L"BaseFolder"] );
	cfg->arguments = marshal_as<std::string>( dictionary[L"Arguments"] );
	cfg->filePath = PathUtil::combine(cfg->workingDir.c_str(), "SomeComponent.exe" );

	cfg->visibility = SW_NORMAL;
	cfg->useNewConsole = false;
	cfg->captureOutput = false;
	cfg->priorityClass = NORMAL_PRIORITY_CLASS;
	cfg->joinTimeout = 3 * 60 * 1000;
	cfg->severity = SEVERITY_CRITICAL;
	cfg->allowAttach = true;

		cfg->coredump = System::Convert::ToBoolean( dictionary[L"CoredumpEnabled"] );
		std::string dumpFolder = dictionary->ContainsKey(L"CoredumpFolder") ? marshal_as<std::string>( dictionary["CoredumpFolder"] ):"app://";
		cfg->coredumpLevel = Sys::Diagnostic::CoreDumpWriter::Full;
		cfg->coredumpFolder = PathUtil::resolve( dumpFolder.c_str() );

	auto service = gcnew SomeComponentNativeHostWrapper(cfg.detach());
	return service;

Open in new window

rovermAuthor Commented:
@jkr: "There is no such thing as function pointers in managed code.". As far as I know you can create a delegate (Delegate.Create method) and get it's pointer using MarshalAs.GetFunctionPointer...

@ambience: Yes, I saw C++/CLI before but this is completely new to me. Do you know any good and quick tutorial?
Minh Võ CôngCommented:
It's easy to import function c++ dll to C#, import class more complex
you can read the topic:

Solution A: Create Bridge Functions in C and Use PInvoke
Solution B: Create a Bridge DLL in Managed C++
rovermAuthor Commented:
Hi minhvc,

Thanks for your comments, I will look into it.
rovermAuthor Commented:
Hi all,
I am closing this Q. The problem was not solved but I am sure your methods would do the trick.
Thanks for your efforts.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.