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.
Related
I'm attempting to bring FMOD Core 2.02 into my Monogame 3.8 project using the dll's and C# wrappers (which appear to be auto-generated from the C++). I've set the .dll's to Copy to the output directory on build, and I'm accessing them like so:
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string path);
public void OnSystemLoad()
{
if (Environment.Is64BitProcess)
LoadLibrary(System.IO.Path.GetFullPath("FMOD\\x64\\fmod.dll"));
else
LoadLibrary(System.IO.Path.GetFullPath("FMOD\\x86\\fmod.dll"));
}
Everything's working just fine up to this point, the .dll's accessible from the pointer. However, once I go to create a new FMOD System using:
FMOD.Factory.System_Create(out FMODSystem);
I get this error in a popup window:
The procedure entry point ?setFadePointRamp#ChannelControl#FMOD##QEAA?AW4FMOD_RESULT##_KM#Z could not be located in the dynamic link library ...fmod.dll.
Followed by this error on the auto generated C# code itself:
System.DllNotFoundException: 'Unable to load DLL 'fmod' or one of its dependencies: The specified module could not be found. (0x8007007E)'
I'm confidant that the .dll is being found just fine, because if I intentionally mess with the Path to something incorrect then the first error never appears.
Has anybody successfully integrated FMOD with Monogame in 2021? If so, please advise, would love any guidance on getting this up and running... don't want to be stuck with Monogame's MediaPlayer!
Other resources I've found on this subject (none of which have worked for me so far):
https://mysteriousspace.com/2015/05/31/fmod-in-c-its-a-pain-to-set-up-heres-how-i-did-it/
https://github.com/Martenfur/ChaiFoxes.FMODAudio
Managed to solve this by reverting to an older release of FMOD, version 2.01.
I'll write a ticket to let the FMOD team know, but my hopes aren't high, since they don't seem to care much for C# beyond Unity.
I am aware of this similar question, but it does not respond to my problem.
I have written two .dlls using Visual Studio 2010. One is in C++, and communicates with an SDK that was written in C++. The other is a C# wrapper for that C++ library, so that it can be used in C# contexts.
My plan was that this would let me use my code in Unity3D, but apparently that is not the case. It seems like Unity3D does not allow me to import .dlls as Assets if they are not a .NET assembly. So I can add my C# wrapper, but not the C++ dll.
This results in a DllNotFoundException whenever I try to access the C++ library. I have tried simply copying the C++ library into the Assets/Plugins folder, but that gives the same results.
Is there a way to do this properly? This is a very vital part of my project setup.
The problem is that the DLL is not being found when the p/invoke runtime code calls LoadLibrary(YourNativeDllName).
You could resolve this by making sure that your DLL is on the DLL search path at the point where the first p/invoke call to it is made. For example by calling SetDllDirectory.
The solution that I personally prefer is for your managed code to p/invoke a call to LoadLibrary passing the full absolute path to the native DLL. That way when the subsequent p/invoke induced call to LoadLibrary(YourNativeDllName) is make, your native DLL is already in the process and so will be used.
internal static class NativeMethods
{
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern IntPtr LoadLibrary(
string lpFileName
);
}
And then somewhere in your code:
private static IntPtr lib;
....
public static void LoadNativeDll(string FileName)
{
if (lib != IntPtr.Zero)
{
return;
}
lib = NativeMethods.LoadLibrary(FileName);
if (lib == IntPtr.Zero)
{
throw new Win32Exception();
}
}
Just make sure that you call LoadNativeDll passing the full path to the native library, before you call any of the p/invokes to that native library.
Note that the DllNotFoundException can be caused by building your Unity DLL in Debug instead of Release!
A simple oversight that can cause a headache.
This also happens when Unity can find your DLL, but is not able to find it's dependencies. Obvious fix is to place dependency DLLs into /Plugins as well, or link your dependencies statically.
Less obvious reason is when your DLL depends on Visual Studio runtime library dynamically, i.e. is built with Properties -> C/C++ -> Code Generation -> /MD option. Change it to /MT to link with runtime statically.
Background
I have an embedded system which runs an application originally written in C++ and compiled in Visual Studio, which results in a single executable and more than 30 DLLs. These libraries cannot be browsed in VS Object Browser or other tools such as P/Invoke Interop Assistant.
Loading some of the DLLs in Dependency Walker shows that all of them are missing some dependencies deep in their dependency tree (cdfview.dll, dwmapi.dll, w32topl.dll, ...) but according to this question, that is likely not an issue.
I have some of the source code files, and all of the compiled DLLs. The application currently runs without issue, indicating there are no real dependency issues.
I am trying to call some library functions and eventually make a wrapper using C#, but am unable to successfully import and call even the simplest of functions. I always receive the following error:
Unable to load DLL 'dllName.dll': A dynamic link library (DLL)
initialization routine failed. (Exception from HRESULT: 0x8007045A)
Sample Code [EDITED]
From the C++ source code header file I have the following declarations:
#define OB_API __declspec(dllexport) __cdecl
typedef unsigned long DWORD; // From windef.h
typedef DWORD OBSTATUS;
OBSTATUS OB_API TestObj(void);
In the C++ source code file the following definition is given (which would seem to always return true):
BOOL WINAPI DllMain(HANDLE /* hModule */,
DWORD ul_reason_for_call,
LPVOID /* lpReserved */
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_PROCESS_DETACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
In my C# application class, I add the following declaration:
[DllImport(#"dllName.dll", CallingConvention=CallingConvention.Cdecl)
public static extern ulong TestObj();
The DLL and C# application binary reside in the same directory.
Questions
From researching the error, it seems there is a large number of reasons this particular exception could be thrown and I was wondering how I could further troubleshoot this type of issue.
Is there any way to get more detailed information on why the initialization routine failed?
(Note: target system is running .NET framework 2.0)
The DLL you are loading contains a DllMain() function. That's pretty common, such a function initializes the state of the DLL. Windows makes sure that this function is called whenever the DLL gets loaded, it will happen automatically the first time you pinvoke a function exported by that DLL.
Problem is, that function returned FALSE to indicate that it could not properly initialize the DLL. That of course does not give a wholeheckofalot of information about why it returned FALSE. Windows can't do anything but generate error 1114, ERROR_DLL_INIT_FAILED. If the DLL itself doesn't output any diagnostic then you can't do anything but debug the code. Start with Project + Properties, Debug tab, tick the "Enable unmanaged code debugging" option.
Fingers crossed that you see a message in the Output window. Odds are not very good. If you don't have the source code for the DLL then you'll need the help of the vendor or author of the DLL. Give him a copy of a test project that fails like this.
Maybe the reason is need to install old Net Framework version like 2.0, 3.0, 3.5,....it's worked for me :D
I have a C# winapp. I call a native .dll file (created in C++ by myself) from the C# app, and it works fine.
But when I copy my application (.exe and .dll files) to another machine, I get an error that says:
Unable to load DLL "c:\dllname.dll": The specified module could not be found. (Exception from HRESULT: 0x8007007E)
Here is the C# code:
class IsoMessageHelper
{
public const string ISO8583_DLL = "c:\\Hc8583.dll";
[DllImport(ISO8583_DLL, CallingConvention = CallingConvention.Cdecl)]
public static extern bool InitializationRq(...)
}
What should I do?
A common issue when deploying .Net applications that have native dependencies, is that the native dlls may be missing dependencies themselves on the target machines e.g. the correct version of the C runtime.
Use a tool such a Dependency Walker to analyze your native dll and determine if it has a missing dependency on the machine you have copied it too.
Try not to hard code any paths in the DllImport attribute parameter that specifies the name of the file. Then you should make usre the file is right besides the executable.
Something like this:
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
Move the DLL to the root. If that works, then look at your attribute to determine why. You haven't posted any code, so I can't give you any specific reason.
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.