[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 480
  • Last Modified:

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);
} PARAMETERS

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

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.
0
roverm
Asked:
roverm
  • 4
  • 2
  • 2
  • +1
2 Solutions
 
jkrCommented:
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.
0
 
rovermAuthor Commented:
What do you mean?
0
 
jkrCommented:
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.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
ambienceCommented:
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: http://msdn.microsoft.com/en-us/library/ektebyzx.aspx
0
 
ambienceCommented:
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;

	if(dictionary->ContainsKey(L"CoredumpEnabled"))
	{
		cfg->coredump = System::Convert::ToBoolean( dictionary[L"CoredumpEnabled"] );
	}
	if(cfg->coredump)
	{
		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

0
 
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?
0
 
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++

http://www.codeproject.com/Articles/18032/How-to-Marshal-a-C-Class
http://www.codeproject.com/Articles/14180/Using-Unmanaged-C-Libraries-DLLs-in-NET-Applicatio
0
 
rovermAuthor Commented:
Hi minhvc,

Thanks for your comments, I will look into it.
0
 
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.

RoverM
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 4
  • 2
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now