Calling convention for an unmanaged DLL in C# - c#

I created a DLL in C++ and loaded in C# with [DllImport].
Is __cdecl default in C++ when exporting without calling convention?
Is it okay to use CallingConvention.StdCall or CallingConvention.Winapi with the function __cdecl? (It worked in my test, and I don't use 'Variable Arguments')

Is __cdecl default in C++ when exporting without calling convention?
Yes.
Is it okay to use CallingConvention.StdCall or CallingConvention.Winapi with the function __cdecl?
No. Use CallingConvention.Cdecl. Using the wrong calling convention might appear to work for some functions, but it is wrong, and at some point you will be caught out.

Related

How to give a C# DLL a C-compliant interface?

A third-party app I have can call extension DLLs if they have C-compliant interfaces as described below.
I would like the third-party app to call my C# DLL, since I would rather write in C# than C. (Maybe my other choice would be to write a C DLL wrapper to call my C# DLL, which is an extra step that I might not get right).
I've searched the net and SO but haven't found (or recognized) a good match to my question.
The best suggestion seemed to be this special marshalling declarations in the C# code here: Calling a C# DLL from C; linking problems
Is it possible to write a C# DLL that has a C-compliant interface like the one below? If so, could someone tell me what I have to do or point me to some documentation?
The third-party app documentation says, "The DLL function must be a PASCAL function that takes a single LPCSTR (long pointer to a constant string) argument. C or C++ DLL functions called must have prototypes equivalent to:
extern "C" __declspec(dllexport) void __stdcall fn(LPCTSTR szParam );
Take a look at this article: https://www.codeproject.com/Articles/12512/Using-the-CDECL-calling-convention-in-C-changing
It discusses a different problem (opposite to yours) but also explains the linkage of C# functions - by default C# uses __stdcall (and it cannot be overridden). This means your third party app should be able to call the C# function as it stands. Have you tried it? Did you get any errors?

__vectorcall via C++/CLI or PInvoke (C#)

Is there any way to invoke C++ functions that use the __vectorcall calling convention via PInvoke or C++/ CLI? So far my attempts have suggested this is not possible (yet). Figured I would ask here to see if anyone knew of a creative way.
You could create a forwarding function in C++ that takes its arguments in the normal way (cdecl), then forwards those on to the function that expects them in __vectorcall.
You cannot invoke __vectorcall with p/invoke but you can using C++/CLI.
There's nothing special about doing so from C++/CLI. The C++ compiler has support, you can simply declare functions with this calling convention and call them.

Passing C# class between C++ functions

I am wondering if it is possible to pass my invoked C# object between c++ functions? I can already call my C# dlls from my native code, but now I need to pass a object between c++ functions which also means that I need to declare it in the header file...
When defining it in my header file I get the following error:
BOOL Exists(Api ^api);
Error 60 error C3395: 'ApiBase' : __declspec(dllexport) cannot be applied to a function with the __clrcall calling convention
Does anyone know how I should handle this in my header?
You use __declspec(dllexport) to export a native C++ class. But it sounds like your class is a managed .net ref class. If you wish to export the functionality for both managed clients and unmanaged clients you need to declare two classes. One a managed ref class, and one a native class.
Or perhaps the issue is that you are trying to export a function that has managed parameters with __declspec(dllexport). Again that is not possible.

How can I call a function of a C++ DLL that accepts a parameter of type stringstream from C#?

I want to import an unmanaged C++ DLL and call a function that takes stringstream as a parameter. In C#, there is no stringstream class, so can anyone tell me how to call such a function from a C# program?
You should not expose templated objects via a DLL, period.
Templated objects (e.g. almost everything in std::) become inlined. So in this way, your DLL gets its own private copy of the implementation. The module calling your DLL will also get its own private implementation of stringstream. Passing between them means you are inadvertently weaving two unrelated implementations together. For many projects, if you are using the exact same build settings, it's probably no problem.
But even if you use the same compiler, and mix a release DLL with a debug EXE, you will find stack / heap corruption and other harder-to-find problems.
And that's only using your DLL from another unmanaged C++ exe/dll. Crossing then the lines to .NET is even more of a problem.
The solution is to change your DLL's interface to something that plays friendly across DLL bounds. Either COM (you could use IStream for example), or just a C-style interface like the winapi.
If you can modify the C++ dll, export a plain string version. Otherwise you have to build a managed C++ wrapper project, import the other C++ dll, export it as a managed function, and call that from your C# code. C++ interop really sucks.
I'm afraid that you're going to have to create your own StringStream class in C# in order to be able to consume the functions exported from that DLL. As you mentioned, the .NET Framework doesn't provide any similar class out of the box.
The easiest way is probably to wrap the StringBuilder class provided by the .NET Framework such that it can function as a stream. See this blog post for a further explanation and some sample code.
A similar question was also answered in MSDN Magazine: http://msdn.microsoft.com/en-us/magazine/cc163768.aspx. You might find some of the hints and/or sample code given there useful.
You are trying to bind native C++ code to managed code in C#. Best way of doing that in general is to introduce middle layer in managed C++ that will provide interface to calls from C#.
Create an Wrapper dll in c, or c++ that exposes an friendly call to that function. It's the better way.
for example an
BOOL getString(TCHAR * myreturnString, DWORD *size);

Marshalling reference-types from C++ to C#

I want to invoke the following C++ function (exported by a DLL) from C#:
void createVm(
const jace::VmLoader& loader,
const jace::OptionList& options,
bool ignoreUnrecognized = true );
I've found documentation for marshaling primitives from C++ to C# but I'm not sure how to handle reference-types or non-pritmive types such as VmLoader or OptionList (both of which are classes). I'm trying to wrap a C++ API with a C# layer, delegating to the underlying C++ code for the actual method implementation.
Any ideas?
AFAIK, PInvoking into a function with C++ constructs is not a supported operation. You could probably get it to work but I think you'll find problems.
What is supported is writing a simple C wrapper function which calls into your C++ function. PInvoke into the wrapper function instead and that will do the trick.
Assuming the c++ DLL correctly exports the types being passed by reference, you could right a light weight managed C++ wrapper that calls the dll. With managed c++ you can call native C/C++ libs and dlls directly while still exporting a managed interface from the resulting assemblies. Other .Net languages can call the managed interface just like they would any other assembly. It's a bit of extra overhead, but's is can be the quickest way to get it done.

Categories

Resources