Calling C++ DLLs from ASP.NET 4 - c#

I'm trying to call a C++ DLL from ASP.NET 4.0 web application but keep getting a DLL Import error - unable to load library 'Library name'.
I've read a lot of blogs where developers experience the same probem and what seems to be working for most people is adding the path to where the unmanaged DLLs are to the PATH Environment Variable
I've done the same on the server and double, tripple checked that I spalled the path correctly and that the C++ DLLs are in that folder but when I view the application in the browser I'm still getting the same error.I've placed logging in the code and it's definitely coming from the portion of code which calls the unmanaged DLL.
Here is some information on my environment:
Windows Server 2003
IIS 6.0
.NET Framework 4.0
ASP.NET MVC 4.0
C#
On the dev machine it works if I copy the unmamanaged DLLs to C:\Program Files\IIS Express
Tried copying the C++ DLLs to the bin folder but as far as I understand ASP.NET copies the DLLs from the bin folder in inetpub\wwwroot\sitename\bin to a dynamic location when it executes the code but this process excludes the unmanaged DLLs.Any advice on what else I can try?
EDIT:
In terms of the code it's exactly the same as any other interop code,I have a wrapper class where I use DllImport to define all th required function calls and in my code I create a new instance of the wrapper and call the required function.As I mentioned this works fine on the dev machine as long as the C++ DLLs are i the IISExpress folder but when I deploy to the server it throws the above mentioned error:
[DllImport("My3rdparty.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int myfunction(int handle, int* response, int timer);

So after weeks of struggling I came up with a work around.The integration that I was implementing was for credit card processing. Along with the C++ DLLs they also have a compiled configuration file called system.dna and my suspicion is that when you add the folder containing the interop DLLs to the PATH Environment Variables it does not pick up the system.dna file.
As a workaround I created a WCF service which is installed as a Windows Service on the server and I've placed the logic for doing payments into this service and the web application simply talks to the service.I hope this helps other developers who are facing the same issue

Related

Utilizing a Managed C# DLL from an ETL Tool via a Mixed-Mode C++/CLI DLL - Possible?

I am working within a 32-bit ETL tool (Pervasive Data Integrator v9). I need to give this tool the ability to call an external function that will remove a file from within a ZIP archive without extracting the archive.
The ETL tool provides the ability to load an external DLL and call its functions. The DLL and its function gets referenced by ETL tool's custom script language like this:
Declare function OemToCharA lib "user32" (byval lpszSrc as string, byval lpszDst as string) as long
The function (OemToCharA in this example) is then called somewhere in the lines of the script that follow that declaration. I have tested this with a registered DLL and it works.
So I want to build a DLL with a function that will do the zip manipulation.
Since I don't know how to manipulate zip files programatically, I found DotNetZip - a free .NET class library that provides the heavy lifting for the zip archive operations. Problem for me is that it is .NET (managed). I would still like to try to use it. So I built a C# DLL (.NET 4.0) with a function that utilizes DotNetZip to do the required zip file manipulation. I pass in two parameters, "zip file location" and the "file to remove" and the zip archive gets updated.
I read about the idea of building a mixed-mode C++/CLI DLL to take advantage of managed .NET code in the native world. I found this VS solution which consists of 3 basic projects:
Managed (C#) DLL project
Mixed-mode C++ DLL wrapper project which references the C# DLL
A native (unmanaged) C++ console test app project which references the C++ wrapper
I built a test solution based on that pattern which removes a file from a zip archive and it works great. Please note however that the mixed mode DLL is called from a native C++ console app which is part of the VS solution. I didn't have to register any DLLs and it just works.
However ultimately I need the ETL tool to call the mixed mode DLL. I am not able to get this to work.
Things I have tried on the ETL server thus far:
I tried to register the mixed-mode wrapper DLL but SysWow64\regsvr32 fails to find an entry point in the DLL.
I installed VS 2015 VC++ x86 and x64 redistributable libraries on the ETL server.
I placed the DLLs from my solution (i.e., the mixed mode, c# and dotnetzip dlls) in the ETL engine folder because the console app worked when the DLLs were in its deploy folder.
The ETL tool has the ability to call an external application so I believe I could let it call a console app similar to my VS test solution but I'd really like to get this to work with only the DLLs. Is this possible? If so, what am I missing?
Kudos to Matt, thanks for the hint to use Process Monitor.
ETL tool was not finding the DLL but Process Monitor told me the folders it was checking...I moved the DLLs to one of the checked folders
My wrapper function was originally void with an output parameter for the return value - that was causing issues as I didn't have a good example in the ETL documentation of how to call a void function. I changed the function to return a "long" and removed the output parameter.
After making those two changes it started working. Thanks again Matt!

missing method exception can't find pinvoke dll

I will give you a brief description of my software before I ask questions.
So there is a front end C# code which provides the user interface and a back end C++ code that deals with the hardware.
The C# project creates an executable (.exe) file and the C++ project creates a DLL which talk with each other using pinvoke calls (import/export functions). All this worked fine on WEC7.
Now, we are moving to WEC2013 with Toradex. I downloaded the WEC2013 SDK from Toradex’s website and was able to port my code and build it on VS2013.
I copied all the required files on a USB and when I tried running it the C# exe is not able to communicate with the C++ Dll. The error I get is :
missingmethodexception can't find pinvoke dll “xyz.dll”
I have made sure the dll exists at the specified location. The dll also has the required export functions.
First I thought the function parameters in the export functions could be an issue, but I tried calling function which requires no parameter with the same result.
Any help will be really appreciated.

DllNotFoundException From C# but not VB.NET

I have a third party DLL to integrate with their application. It is a 32 bit C++ DLL that does not expose itself via COM, and I have not been supplied source code or a header file.
It was supplied with working VB.NET example code in a WinForms example. This works, as long as the executable is run from the same directory as the API DLL and the application for which the API is interfacing.
I was using the example function declaration:
Declare Ansi Function GetVersion Lib "ThirdPartyAPI.dll" () As Integer
However, we’ll be using the API calls from a C# library to be used in a web site or web service, so I converted the example VB code to
[DllImport("ThirdPartyAPI.dll", SetLastError = true, CharSet = CharSet.Ansi)]
public static extern int GetVersion();
If I call this from within the C# library I get the error
Unhandled Exception: System.DllNotFoundException: Unable to load DLL
'ThirdPartyAPI.dll': A dynamic link library (DLL) initialization
routine failed. (Exception from HRESULT: 0x8007045A)
I took an alternative route and put the original working VB code from the example into its own VB.NET DLL and called that via C#. I got the same error. Strangely, a call to the VB.NET DLL from a VB.NET console app works.
In summary:
A simple VB.NET console app will work
A simple VB.NET WinForms app will work
A simple VB.NET console app can call GetVersion via a VB.NET DLL
A simple C# console app cannot call GetVersion via a VB.NET DLL
A simple C# console app cannot call GetVersion directly.
This could be to do with incorrectly defining the function calls. At
this stage, I’m not too worried about this.
32 bit compilation does not fix the issue
I have tried this on Server 2008 R2 and Windows 7 Enterprise
I created a WCF host via an NT service to expose the functions, hoping this would work around file locations and dependencies. This was written in VB.NET and placed in the same folder as ThirdPartyApi.dll.
None of the code in the NT service could access GetVersion
None of the code in the WCF service could access GetVersion
Please note, in all of the above cases, the executables are in the same directory as ThirdPartyApi.dll. All of its dependencies also exist in this directory.
Can anyone explain this behaviour, or suggest how this can be made to work within a C# web site?
Thanks
The error code is 0x8007045A. That is a COM error code that maps to the Win32 error code ERROR_DLL_INIT_FAILED. Which is described as:
A dynamic link library (DLL) initialization routine failed.
What this means is that your DLL was found, in spite of the perhaps misleading exception class DllNotFoundException. However, the DLL failed to load. You can gain no more information from the system. There is no mechanism for the DLL to report reasons why it failed to load. I suggest that you contact the vendor of the DLL and ask for support.

Configuration system failed to initialize from c# com dll

I have com dll written in c# and everything works ok when I use it from the normal exe project in visual basic 6, but when I try to use it from the visual basic 6 dll then I get this error: configuration system failed to initialize. This is a dll, so it don't have any app.config file.
I get this error on this line:
request = (HttpWebRequest)WebRequest.Create(ApiUrl);
where ApiUrl is something like: https://www.api.com/
Anyone knows what can be wrong?
Edit:
Maybe there is something with permissions? The vb6 dll is called from the web service hosted on the iis on the same server.
Edit2:
It must be something with IIS_USER, because when I call the vb6 dll from normal exe project, then works.
The impression I get of your setup is:
You have a client (of some sort) that is connecting to a web service that is written in C#, that is calling a VB6 dll that in turn calls a COM-exposed C# dll?
When I've seen this error in the past, I've had multiple Configuration elements in the *.config file. You will have a *.config file for the main service, so I'd start looking there.
A quick google found this URL which backs what I've found in the past too: http://social.msdn.microsoft.com/Forums/vstudio/en-US/b7603703-3805-4e73-ac6a-755a7c14e722/configuration-system-failed-to-initialize?forum=vbgeneral
(apologies for offering as an answer, I can't add comments due to having <50 rep)

c# Web Service referencing c# project referencing DLL

Alright, so maybe this is inadvisable, but I'm writing a Web Service for an existing application. I'm trying to use the C# Library we wrote for the project, and that C# Library uses functions from a dll that is not acreated from a .NET project. I know the DLL isn't a problem, because the actual application (A windows form application) that uses the c# Library has no problem performing operations that use this dll, but my web service always crashes when the dll methods are called. The exception is:
"Unable to load DLL 'foo.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)"} System.Exception {System.DllNotFoundException}
A sample of the import from the c# Library:
[DllImport("foo.dll")]
protected static extern void DllFunction(string param1, int param2, int param3);
I tried adding foo.dll to the Bin directory of my project, but this didn't work. I feel like I must be missing something really obvious. Any suggestions? I've read some funky things about DLLs and web services and tried a couple of fixes such as http://sites.google.com/site/tosapage/programming/asp-net#dll but they didn't work.
I would run the winforms exe with depends.exe. You might be getting that error for a dell that the dll you are calling needs.

Categories