I have a old DLL (Borland Builder 2006 C++) which I want to use in .Net C# Visual Studio 2010. When I try to import the functions in VS always I get a StackOverflowException from Visual Studio. I've already read a lot stuff and the import seems to be easy. But I fail and don't see my error.
In the Borland DLL the Functions are exported as:
__declspec(dllexport) void TestFunc1() or
extern "C" __declspec(dllexport) void __stdcall TestFunc2()
The decorated names are (*.DEF file created with impdef and proved with dependency walker):
#TestFunc1$qqsv
TestFunc2
In Visual Studio I import in this way:
[DllImport("MyDllName.dll", EntryPoint = "#TestFunc1$qqsv", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
public static extern void TestFunc1();
[DllImport("MyDllName.dll",CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
public static extern void TestFunc2();
In booth cases a get a StackOverflowException from Visual studio, when I call:
MyImport_Unmanaged.TestFunc1() or
MyImport_Unmanaged.TestFunc2()
What is wrong ? Can anybody help me ?
Interesting when I import a old dll created with Visual Studio C++ the decorated name of the function is: _TestFunc1#0. The name is quite different to the Borland names but is works.
the correct syntax is:
extern "C" void __stdcall __declspec(dllexport) TestFunc1()
I had the same problem. After a lot of experiments I realized that the problem was not a syntax one. It was the fact that the C++ Builder DLL was using VCL Forms. I removed the forms and everything worked.
Yes, Panos seems to be right. I tried to P/Invoke an old BCB5 DLL with VCL and at the
first look it worked quite OK. But it silently has corrupted the C# program which manifests in strange exceptions a little bit later.
Not using the VCL in the Borland DLL was the only way to get it work. For us this means we have to convert our code to VisualStuidio which is on out todo-list anyway.
Related
I want to use a C++ library for my asp.net website. I don't know how to make a .dll of the library and make it work. I tried making a dll and import it to asp.net. Do I need a to do something in the c++ code for the dll to work?
Source code: http://warp.povusers.org/FunctionParser/fparser.html
You could use:
[DllImport("dllname.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern double FunctionParser();
I'm trying to import a C++ Project Dll into a C# project. I found a lot of people talk about using DllImport. I tried using that and here is what I have-
CPP Code:
int __declspec(dllexport) beginCode(double reportId);
C# Code:
[DllImport("C:\\Users\\<my_user_id>\\Desktop\\ctxmix\\Release\\ctxmix.dll",CallingConvention =CallingConvention.Cdecl ,CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
public static extern int beginCode(double reportId);
int result = beginCode(reportId);
But when I run, I'm getting an exception - Exception thrown:
System.DllNotFoundException
Do I have to add any references for the CPP Dll in the project or do anything else apart from the code which I have on the top?
Edit: I'm trying to run my .exe using VS2015 and I get this exception on my local machine. Also, I don't see my CPP Dll in the Project->References section where as I see other references there.
The unmanaged DLL needs to be locateable by your managed process. Typically that means placing the DLL in the same directory as the executable file. But you gave used an absolute path which I presume you transcribed correctly.
You may also encounter this error if the DLL's dependencies cannot be located. That seems the likely explanation here. Most likely the MSVC runtime cannot be located when your DLL is loaded.
Using an absolute path isn't a great idea. That will break down when you distribute to another machine. Use just the DLL file name and place it in the same directory as the executable.
Your DllImport attribute seems fussy. No point specifying CharSet when there is no text. I doubt your function calls SetLastError. And do you really need ExactSpelling?
I've a very interesting problem. It's sounds very easily, but I didn't finf any information about it.
I've a C# solution with excel Add-in and winforms application and library project with only one method.
project with library have next code:
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi)]
public static extern IntPtr LoadLibrary(string filename);
public sealed class LibraryInfo
{
public readonly IntPtr Handle;
public LibraryInfo(string dllName)
{
Handle = LoadLibrary(dllName);
}
}
public LibraryInfo GetLib(string name)
{
return new LibraryInfo(name);
}
Look's like simple.
So I've a call of that method from add-ins and from WinForms
I've a Dll, builded for x64 platform and x86 platform.
And now magic:
LoadLibrary returns error code 127 only when I run it from Add-in and x64 configuration and on excel-2016(x64, ofcourse). When I run it on x86, or winform (both x86 and x64) it works. And it is not all, when I run it on Excel 2013 it's works fine too!!!
mayby somebody knows?
Error code 127 is ERROR_PROC_NOT_FOUND.
The specified procedure could not be found.
Typically that means that something is calling GetProcAddress which is failing because the module in question does not export a function of the specified name.
Exactly where that is happening cannot be discerned from the code that you supplied. Unfortunately you did not supply very much code, and did not supply the code that you are using. That much can be discerned from the fact that you mention an error code in spite of the code in your question performing no error checking.
It could be that code you did not show is calling GetProcAddress and failing. Or it could be that the loader is yielding that error code whilst resolving the dependencies of the library you load.
So, what I've stated above is a broad explanation for the behaviour that you report. Anything more specific would require the actual code in use, but only you have that code.
Problem solved.
I ve a dependent dll for my, called "Chart", so excel 2016 have "chart.dll", 2013 - not.
The solution is rename my "chart.dll" and rebuild both of dlls.
I got a DLL that I want to add to my C# project and I have some problems. First, my DLL is coded in C++ and I got an interface of one function to export it.
extern "C" __declspec(dllexport) char* sniff()
{
return ps.Sniff();
}
I have an instance "ps" that initialise a socket when the DLL is attached. The point is that I need to have this instance initialise when I call my exported function. My problem is when I import it in my C# project, my DLL is detached for no apparent reason and I can no longer call my exported function.
I use this syntax in my C# projet :
[DllImport(#"C:\Documents and Settings\Pat\Bureau\sniffoporn\Release\sniff.dll", EntryPoint = "sniff", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr sniff();
Some important things that I tryed :
Import the DLL in the reference of the project : Can't because it's not a COM component.
Manually import the DLL using LoadLibrary, FreeLibrary and GetProcAddress : Same result
Call my exported function in loop : Same thing but the DLL is attached for a little longer before detaching.
I would want to know why my DLL is detaching and how can I keep it attached for the rest of the process life.
Thanks a lot
Maybe an exception occurs in your DLL itself. Making it detach in Visual Studio to prevent your application from crashing. After all C# is managed code.
Try your same procedures with a different (dummy) dll with very simple functionality. If it still occurs then something with your method is wrong, otherwise with the DLL you are attempting to use.
I'm getting this weird error on some stuff I've been using for quite a while. It may be a new thing in Visual Studio 2010 but I'm not sure.
I'm trying to call a unamanged function written in C++ from C#.
From what I've read on the internet and the error message itself it's got something to do with the fact that the signature in my C# file is not the same as the one from C++ but I really can't see it.
First of all this is my unamanged function below:
TEngine GCreateEngine(int width,int height,int depth,int deviceType);
And here is my function in C#:
[DllImport("Engine.dll", EntryPoint = "GCreateEngine", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr CreateEngine(int width,int height,int depth,int device);
When I debug into C++ I see all arguments just fine so thus I can only think it's got something to do with transforming from TEngine (which is a pointer to a class named CEngine) to IntPtr. I've used this before in VS2008 with no problem.
I had a _cdecl c++ dll that I called without any trouble from Visual Studio 2008, and then the identical code in Visual Studio 2010 would not work. I got the same PInvoke ... has unbalanced the stack error as well.
The solution for me was to specify the calling convention in the DllImport(...) attribute:
From:
[DllImport(CudaLibDir)]
To:
[DllImport(CudaLibDir, CallingConvention = CallingConvention.Cdecl)]
I guess they changed the default calling convention for DLLImport between .NET 3.5 and .NET 4.0?
It could also be that in the .NET Framework version 3.5, the pInvokeStackImbalance MDA is disabled by default. Under 4.0 (or maybe VS2010) it is enabled by default.
Yes. Technically, the code was always wrong, and previous versions of
the framework silently corrected it.
To quote the .NET Framework 4 Migration Issues document: "To improve
performance in interoperability with unmanaged code, incorrect calling
conventions in a platform invoke now cause the application to fail. In
previous versions, the marshaling layer resolved these errors up the
stack... If you have binaries that cannot be updated, you can include
the <NetFx40_PInvokeStackResilience> element in your application's configuration file to enable calling
errors to be resolved up the stack as in earlier versions. However,
this may affect the performance of your application."
An easy way to fix this is to specify the calling convention and make sure it is the same as in the DLL. A __declspec(dllexport) should yield a cdecl format.
[DllImport("foo.dll", CallingConvention = CallingConvention.Cdecl)]
Maybe the problem lies in the calling convention. Are you sure the unmanaged function was compiled as stdcall and not something else ( i would guess fastcall ) ?
Use the following code, if say your DLL has the name MyDLL.dll and you want to use the function MyFunction within the Dll
[DllImport("MyDLL.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
public static extern void MyFunction();
this worked for me.
In my case (VB 2010 and DLL compiled with Intel Fortran 2011 XE) the problem exists when my application targets .NET Framework 4. If I change targeted framework to version 3.5, then everything works fine as expected.
So, I would guess the reason is something introduced in .Net Framework 4 but I have no idea at the moment which one
Update: The problem was solved by recompiling Fortran DLL and explicitly specifying STDCALL as calling convention for export names in the DLL.