Yes, the name of your function was mangled – since c++ supports namespaces, classes, and overloaded functions, it cannot use a function name as-is in object code, so mangles it according to some internal rules. This is also why we use extern “C” on functions we wish to export for pinvoke (c does not support overloading, so mangling is not done).
This is going to provide your first big hurdle, since if the software company is not giving you any headers or libs, then while you may be able to retrieve the mangled function names using a tool like that, you will still not know the function signatures. For trivial cases it may be possible to correctly determine the signature, but we don’t know that, especially as the library in question is not your own (see here for a taste of what you’re up against)
However, let’s say for sake of argument that you are able to demangle all functions you want to call, with their signatures. Well, with those in hand, you may as well directly pinvoke them, and use your native dll solely for hosting the clr – you know the dll they come from, since that’s the same one from which you just retreived and demangled names, so you can make the pinvoke declarations. Your native dll is only the hook you need to get injected into the process, and spin up the clr.
I must say at this point, for you or anyone reading this, that this is all completely unsuitable (for reasons which should be obvious by now) for anything but personal toy code. You don’t own the dll, and even if you could decode all its functions, you cannot know when they may change. Depending, it may also be risky in the sense that it could be against the non-developer license, to reverse-engineer an API that is otherwise officially provided under an available developer license.
Regarding something like args*,kwargs** in c/c++, there is indeed support for something like this (variadic functions), for example as you see with printf(const char*,…). However it is not something that will just magically do what you want here. When we talk about writing wrapper functions, we mean, using pinvoke to take a native function and expose it in dotnet, carefully and correctly translating (marshalling, we say) data between the two worlds. This is hard work, and there is not as yet any silver bullet I’m aware of, except in cases where it is acceptable to use c++/cli.
The * in c and c++ means pointer to. So you may have an int, and then also an int* that points to it. In the code you have above, you have used typedef to delcare a function signature named func, and then you have cast the result of GetProcAddress to func*, or pointer to func, and then called it.
And a tilde in front of a class name marks the class destructor method:
class MyClass
{
public:
MyClass() { /* constructor */ }
~MyClass() { /* destructor */ }
};