C # DllImport Error

My question is a little general, so I'm not looking for an exact answer, but maybe some guidelines that will help with this will help me ...

At my workplace, I program mainly in C #. We have this third-party company we work with, which gave us the Native C ++ dll that we should use. Since the C ++ method I needed was not disclosed in a way that it was easy to reference C #, I wrapped the dll in another Native C ++ Dll.

So now I have 2 Native C ++ dlls, one of which wraps the other.

I created a small C # console application that calls a method that I created in C ++. My method signature is as follows:

[DllImport("HashMethodWrapper.dll")] [return: MarshalAs(UnmanagedType.LPStr)] private static extern string CreateHash( string input, [MarshalAs(UnmanagedType.LPStr)]StringBuilder output); 

In my console application, everything works fine, and I always get the im string waiting for the result.

But when I go to the web service or the created web application (since this is exactly what I really need), I see that getting the string im is garbage and not even consistent. It seems that I get only some reference to the memory that is lost or something like that, but this is just my guess ...

I do not know why this is happening, since everything works fine in my console application.

Does anyone have a direction that could help me? ...

Thanks in advance, gillyb

Edit: I thought this might be due to some loose objects, so I tried calling the method in a fixed expression, for example:

 unsafe public static string CreateHashWrap(string pass) { String bb; StringBuilder outPass = new StringBuilder(); fixed (char* resultStr = CreateHash(pass, outPass)) { bb = new String(resultStr); } return bb; } 

... but it still did not do this for me. Is it right to link objects?

2nd Edit: The method signature in C ++ looks like this:

 extern "C" __declspec(dllexport) char *CreateRsaHash(char *inputPass, char *hashPass); 

3rd Edit: I replaced the method signature

 extern "C" __declspec(dllexport) bool CreateRsaHash(char *inputPass, char *hashPass); 

and im looks for the return value in the *hashPass parameter.

Now I have created a simple console application to test it. When you insert DllImport into my main class and directly call the method, everything works fine, but when I move DllImport and wrap the method in another class and call this class from the "Main" Console method, I get a StackOverflow exception!

Anyone have any idea why this is happening?

+4
source share
4 answers

I found a solution to my problem, and now I feel curious (if not very!) Stupid ...: - |

I used the LoadLibrary() method in C ++ to dynamically call a method from another native dll. The problem was that I did not give the method any path and just the dll file name. In .net, he would search in the current folder, but it seems that this does not work in the native code.

The big problem in my programming practice, obviously, is that I did not fully cover the error handling in my native C ++ dll!

All the recipients that I received on this page were not in vain, but ...

As soon as I found out that I had problems with the directory, I came across various exceptions about trying to access damaged memory, etc. And then I needed to create pinned objects and declare a size for my StringBuilder object.

Thank you all for your help!

:)

0
source

Try specifying the capacity of StringBuilder before passing it to the interaction method.

+2
source

This is very difficult to learn from rare information, but if I were to guess, I would say that you need to make sure that you are binding the output object. Also, I would probably change the output parameter to some other type, it seems rather strange that StringBuilder works openly.

I know that if you select an object, it will get a pointer, but that does not mean that it will not move. Therefore, if you try to pass a pointer to a managed object in an unmanaged environment, you need to make sure that you tell GC to “lock” the memory so that it does not get out from under you.

Here is a really rough version of what I mean by binding:

 string input = "..."; StringBuilder output = new StringBuilder(); var handle = System.Runtime.InteropServices.GCHandle.Alloc(output, GCHandleType.Pinned); try { CreateHash(input, output); } finally { handle.Free(); } 
+1
source

I would think of deforming inside a common C # / dll assembly instead of a C ++ dll, and then try to get the console application to work with dll. Good practice is to wrap external dependencies this way anyway.
Otherwise, some of the traditional problems are 32 versus 64 bits, the download path to the shared library. Is this really just a string or something more complicated?

0
source

All Articles