0

I have spent several hours looking for the answer so I figured out that if I ask myself I could finally end up with a solution to my problem. First, to describe what I want to do: UNMANAGED CODE NEEDS TO BE SHARED BY WRAPPED DLL AND A SOFTWARE PLATFORM So, to describe the design above, I have a .dll plugin written in pure c++ ( I don't want it to contain any .Net code). This c++ plugin will be used from a software platform. Now, I want the c# windows service to interact with the software platform, but it only can do it through the c++ dll. For this reason, I wrapped all the functionality of the c++ plugin into the Wrapped Dll (I exported the functionality) and I am using the Wrapped Dll into the c# windows service.

Now, I have a test method to check if the export of the c++ functionality is working ok, (just a simple method that returns the sum of two integers) and I can see that the windows service can interract with the c++ unmanaged dll in the correct way, I am getting the correct results. The problem I have is when I try to interact with the Software platform through the c++ unmanaged dll. I get the following error:

Error for corrupt memory

I realized that the error should be because the unmanaged dll cannot be accessed by the Software Platform and the Wrapped Dll at the same time. To solve this, I found out that the solution is to add the unamanaged dll in the GAC. But to put a dll in the GAC, the dll has to have a strong name, but I found out that I cannot sign a strong name to unmanaged code unless I have the /clr option enabled. But when I have this option enabled the unmanaged dll doesn't compile.

To summarize, is there any way I can get my unmanaged dll to be access by the software platform and from the wrapped dll? Without the integration of .Net in my unmanaged code?

I have spent a lot of hours searching for the solution so it would be great if any of you can show me a little light in the tunnel!

Thank you

CompuPlanet
  • 151
  • 1
  • 11
  • It looks like there is something going wrong in your wrapper. I guess some pointer issues. Could you show us more code? – t3chb0t Nov 25 '14 at 09:36
  • @t3chb0t `[DllImport("C:\\Path\\MyNativeDll.dll", EntryPoint = CheckUserGroup")] public static extern bool _CheckUserGroup(string group);` This is how I import a method from the NativeDll into the ManagedDll. `public bool CheckUserGroup(string group) { return _CheckUserGroup(group); }` And this is how it interracts. --> This method interacts with the software platform, gets the result and returns it to the managedDLL and from the managed Dll to the c# windows service. But, – CompuPlanet Nov 25 '14 at 09:47
  • If I use the `[DllImport("C:\\Path\\MyNativeDll.dll", EntryPoint = "TestMethod")] public static extern int _TestMethod(int x, int y); ` which does the calculation on the unmanaged plugin without interracting with the software platform the results I get in the c# windows service are correct. So, this is the reason I am saying that I am not sure that it's an error in the wrapper. – CompuPlanet Nov 25 '14 at 09:48
  • Please add all your dlls in your application folder and do not use `C:\\Path\\MyNativeDll.dll`. Furthermore move all platform dlls to the directory. – BendEg Nov 25 '14 at 09:49
  • I find it is much easier to take C++/CLI for wrapping native code/dll. It can interact with native C++ much better then C#. – t3chb0t Nov 25 '14 at 09:55
  • I have just tried what you are asking, everything is in the same directory. Still I get the same error. I don't think that it has to do with the directories, or the way I am wrapping the unmanaged Dll :( – CompuPlanet Nov 25 '14 at 10:01
  • @t3chb0t yes, I know it would be much more easier to do that. The problem is that if I use c++/CLI to wrap my code i am using .NET, and I don't want to use .Net to the right side of my design (see above the right side). – CompuPlanet Nov 25 '14 at 10:06
  • The C++/CLI wrapper would sit on the left side. It would replace the C# wrapper and compile to .NET but beeing able to talk to the native dll. – t3chb0t Nov 25 '14 at 10:09
  • ok now I get what you are saying. You are saying that I should use another way to wrap the native dll instead of the one I am using. But still, before starting doing this, I don't think that it's the wrapper problem. Because if it was, how can I use the Test method and get correct results? – CompuPlanet Nov 25 '14 at 10:14
  • Can you provider us some code? – BendEg Nov 25 '14 at 10:23
  • `extern "C" MYNATIVEDLL_API bool __cdecl CheckUserGroup(LPCSTR clientGroup)` this is how the method is defined. And inside the method I am calling the API of the software platform to get the UserGroup and I compare it to the one I get as parameter. The functionality is correct as I was using it before. The TestMethod that is working is this: `extern "C" SPOTOPTIONMTPLUGIN_API int __cdecl TestMethod(int x, int y) { return x+y; }` In my first two comments above I am showing you the code in the WrappedDll. This is the code from the Native c++ dll. – CompuPlanet Nov 25 '14 at 10:30
  • Do you have treid this: http://stackoverflow.com/questions/2417494/passing-a-string-variable-as-a-ref-between-a-c-sharp-dll-and-c-dll ? – BendEg Nov 25 '14 at 10:54
  • How should I use it? – CompuPlanet Nov 25 '14 at 11:19

1 Answers1

0

Your unmanaged dll's and all it's dependecies must be in the same folder as your application (.exe). You don't need the GAC. If you want to store your dlls somewhere else, just use:

p(Invoke:

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool SetDllDirectory(string lpPathName);

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool AddDllDirectory(string lpPathName);

And on your application startup:

if (System.Environment.OSVersion.Version.Major > 5)
{
    AddDllDirectory(System.Windows.Forms.Application.StartupPath + "\\bin64");
}
else
{
    SetDllDirectory(System.Windows.Forms.Application.StartupPath + "\\bin64");
}

Also be sure you do not mix up x86 and x64 architexture. Furthermore be sure you are using the right CallingConvention. A good example is this: Unhandled Exception: System.AccessViolationException: Attempted to read or write

Community
  • 1
  • 1
BendEg
  • 20,098
  • 17
  • 57
  • 131
  • Thank you for your answer. I don't have any problem to use the unmanaged dll, either from the software platform or from the c# windows service, as long as what I am trying to do doesn't interfere between the c# and the software platform. I mean, I can access the test method from the c# window service (see the description of the problem) and it is working fine, but if I try to access a method from the unmanaged code that needs to interact with the software platform to do somathing and give the answer back to the c# service, I get the error. – CompuPlanet Nov 25 '14 at 09:32
  • So my problem is not that I cannot access the dll, is that I want to interact from the two edges using the unmanaged code. Any ideas? – CompuPlanet Nov 25 '14 at 09:33
  • Do you have all dll's from your software platform at the right place (in your application folder)? Would you like to explain what your software platform is? – BendEg Nov 25 '14 at 09:46
  • Yes. The software platform is a platform used for financial purposes, it contains information about the clients (usernames, passwords, balances, orders etc.) You can handle how you want the actions to be done (deposits, withdraws etc.) – CompuPlanet Nov 25 '14 at 09:54