Unity: Native Plugin is not found in standalone build on other computers - c#

I have compiled and imported the GameNetworkingSockets library into the unity Plugins folder. When doing a standalone build on my pc and running it, everything works fine, but when running the build on another pc, the dll files are not found. I have confirmed that the dll libraries are included in the builds Data/plugins folder.
internal static class Native
{
private const string nativeLibrary = "GameNetworkingSockets";
[DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)]
internal static extern bool GameNetworkingSockets_Init(IntPtr identity, StringBuilder errorMessage);
}
I have tried moving the dlls into the root folder next to the executable
I have tried changing the minimal api to .net framework
The native Plugins are in the Plugins folder
Also, which is kind of wierd, the set resolution for the game (windowed) is not used on other computers. Thanks in advance and sorry for my bad english :)

Related

DLLImport is showing my current directory in another user machine

I am new to PInvoke, I wanted to update my system volume using C#, I got one C++ dll and I have to just Import that DLL and use the methods to update the volume.
In C# I have written :
public const String DllName = "ChangeVolumeWindows.dll";
[DllImport(DllName, CharSet = CharSet.Auto)]
public static extern void SetSystemVolume(double newVolume, VolumeUnit vUnit);
I have put my dll into the exe path.
It is working fine for my pc , but when I package the app and send it to another machine I getting error " DLL not found "
I have observed that DLLImport is looking for path of my pc, which is not correct
For example:
I have put my dll in C:/User/ABC/Source/App/bin/debug/ChangeVolumeWindows.dll
in some another machine also it is looking for the same path instead of taking dll from C:/User/AnotherMachineUser/Source/App/bin/debug/ChangeVolumeWindows.dll
Can some one suggest where my code is going wrong.
I have tried to put my dll inside the project and the rebuild. Still I am facing the same issue.
Try this:
My.Application.Info.DirectoryPath("\folders\ChangeVolumeWindows.dll")

Unmanaged Exports not showing up in DLL

I have a new project and a test class, method below:
[ComVisible(true)]
[DllExport("Heartbeat2", CallingConvention = CallingConvention.StdCall)]
public static void Heartbeat2(){
//Do stuff here
}
Im using Unmanaged Exports (RGiesecke.DllExport) latest in DotNet 4.6...when running Nirsofts viewer, I do not see my method in the dll http://www.nirsoft.net/utils/dll_export_viewer.html)
I have the platform target to x86 also...what am I doing wrong? I plan on using this in a ruby 1.8.1 program using Win32API
Giesecke's Unmanaged Exports works fine using VS2015, but not in VS2017 or VS2019.
Try downloading VS2015 Community and try your example there.
Be sure you are building for X64 or X86, not Any CPU.
The Unmanaged Exports should generate a DLL, plus a LIB and RES file.
You can check whether the DLL was modified by checking it with one of several fine .Net decompilers, my current favourite is https://www.jetbrains.com/decompiler/

Debugging a failure to access libleveldb with C# on OSX

A C# project I'm interested in uses leveldb via a PInvoke 'wrapper' that works fine on both Windows and Linux but throws the following error on OSX.
src/tcmalloc.cc:331] Attempt to free invalid pointer 0x7f83cb954a00
A minimal example to reproduce the error with is
using System;
using System.Runtime.InteropServices;
namespace leveldb_test2
{
internal static class Native {
[DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr leveldb_options_create();
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("before");
IntPtr handle = Native.leveldb_options_create();
Console.WriteLine("after");
}
}
}
What I've tried
Manually building leveldb
Leveldb was initially installed via homebrew. Not knowing if they do anything magical, I also did a manual build which gave me the same error.
Verifying the method signature
The method signature used with DllImport seems ok, as it's identical to what's used in a wrapper project I found: leveldb-sharp (fwiw; I tried using that project, same error)
Note that original export from leveldb is
extern leveldb_options_t* leveldb_options_create();
I also created my own dll with the same signature and that worked fine. This also confirmed for me that I can correctly enforce which exact library file is being loaded to avoid it using some broken version somewhere else on my system.
Verifying library exports
I dumped the exports using nm to make sure no name mangling is going on, seems fine.
I can also access the library successfully with ctypes in Python.
Try older versions of leveldb
I tried all older versions up to 1.15 from September 2014. All give the same error.
What's next
Ideally, I'd like to be able to debug the native side. However, unlike with Visual Studio on Windows, the OSX Visual Studio Community Edition doesn't have the "Enable native code debugging" option described here. So my question is
How would I go about debugging the native side while initiated from C#?
I believe the latter part of this question is important, because as said before it works fine when initiated from Python. Any tips/hints/help are much appreciated!
PS: a bonus would be the solution to getting the wrapper to work.

Can't find unmanaged DLL using DLLImport

Above is my folder structure. I have a Cordova app and a Windows Runtime Component - IBscanUltimate. The include folder has the C# code calling into the unmanaged IBscanUltimate.dll. Class1.cs is like this:
using System;
namespace IBscanUltimate
{
public sealed class Class1
{
public static String getSDK()
{
IBscanUltimate.DLL.IBSU_SdkVersion a = new DLL.IBSU_SdkVersion();
IBscanUltimate.DLL._IBSU_GetSDKVersion(ref a);
return "SDKVersion: " + a;
}
}
The IBScanUltimateApi.cs & _IBSU_GetSDKVersion look something like this:
internal partial class DLL
{
[DllImport("IBScanUltimate.DLL")]
private static extern int IBSU_GetSDKVersion(ref IBSU_SdkVersion pVerinfo);
public static int _IBSU_GetSDKVersion(ref IBSU_SdkVersion pVerinfo)
{
int nRc = IBSU_STATUS_OK;
nRc = IBSU_GetSDKVersion(ref pVerinfo);
return nRc;
}
}
I have placed the DLL in many locations to see if it'll get picked up and they all have the above properties. But when I try to run my app, it says unable to locate the IBScanUltimate.DLL
This is how the output is coming:
I am not sure what is it that I am doing wrong and why the DLLImport cannot find my dll. Thank you for your help.
Exact error is:
System.DllNotFoundException: Unable to load DLL 'IBScanUltimate.DLL': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
Update #1:
I have come across https://msdn.microsoft.com/en-us/library/windows/desktop/hh447159(v=vs.85).aspx This article is explaining that LoadPackagedLibrary function can be used to load the dll. I am not seeing any example on how to use this in C#.
Update #2:
Specify the search path for DllImport in .NET Mentions that SetDllDirectory or AddDllDirectory can be used. He has a code snippet for SetDllDirectory, but the argument is string[] paths. How would I specify the relative argument?
Update #3:
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool SetDllDirectory(string lpPathName);
public static bool setPath(String path)
{
//Windows.Storage.
//return SetDllDirectory("ms-appx:///");
return SetDllDirectory(path);
}
I tried calling the SetDllDirectory(path) method with various locations that my app should have access to but I am keep getting "false". Few examples that I have tried:
NativeMethods.setPath(Package.Current.InstalledLocation.Path.ToString());
StorageFolder localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
StorageFolder folder = Windows.Storage.KnownFolders.MusicLibrary;
This is where my app is installed:
C:\Users\AAA\App\hello\platforms\windows\build\windows\Debug\x64\AppX
and I can see that my DLL is there. But still I'm getting the exception that DLL cannot be found. Do I have to put something on the manifest regarding this?
Update #4:
I ran a dumpbin on the DLL and i see the below DLL in the dumpbin:
WINUSB.DLL
mfc90.dll
MSVCR90.dll
KERNEL32.dll
USER32.dll
GDI32.dll
VERSION.dll
MSVCP90.dll
SETUPAPI.dll
I guess I'd like to check on each dll above separately to see if my windows runtime can pick it? One of them could be the culprit that's not being loaded?
Update #5:
Upon seeing the answer from Peter Torr - MSFT, and googling for MFC I came across this article https://msdn.microsoft.com/en-us/library/d06h2x6e.aspx Which states:
The MFC classes and their members cannot be used in applications that execute in the Windows Runtime.
I guess to conclude this wild hunt now. I would close this up that the library I tried to load is dependent on libraries not available for Windows Runtime.
I had this feeling because Windows form application would run but the the code converted to Windows Runtime would give the error that the DLL is not being found. Thanks to Peter for guiding in the right direction.
The DLL you are trying to load was clearly built for desktop apps (it has User, GDI, and MFC imports) and will not work as a UWP binary. I suspect also that the DLL does not have the AppContainer flag set (an option you pass to the linker). You will need to find another way to accomplish what you need (if necessary, please make any feature requests via the Windows Platform UserVoice.
I suspect that it can find your DLL just fine, but it fails to find one or more of its dependencies. Unfortunately, both of these cases result in extremely generic DllNotFoundException that mentions the DLL your try to P/Invoke to.
There is an easy way to figure out what's missing! Windows contains a feature called "loader snaps", which, when enabled, will log all the things that Windows DLL loader does for your process. That means it will also print what DLLs it fails to load. To enable it, run this in admin command prompt:
gflags.exe -i "<executableName>.exe" +sls
Where executable name is just the name of your executable without the folder. To see the output, you will also need to enable either native or mixed mode debugger. You can do that in your project properties debugging tab in Visual Studio.
You can read more about load snaps here:
https://blogs.msdn.microsoft.com/junfeng/2006/11/20/debugging-loadlibrary-failures/

DllNotFoundException with HRESULT 0x8007007E when loading 64-bit dll

I downloaded zlib and compiled the library as both Windows 32-bit and Windows 64-bit dll. I now have zlibwapi.dll and zlibwapi64.dll.
The dlls are copied into my application folder and are referenced as follows:
[DllImport(#"zlibwapi.dll", EntryPoint = "uncompress", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = false)]
private static extern int uncompress32(
IntPtr dest,
ref uint destLen,
[In(), MarshalAs(UnmanagedType.LPArray)] byte[] source,
uint sourceLen
);
[DllImport(#"zlibwapi64.dll", EntryPoint = "uncompress", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = false)]
private static extern int uncompress64(
IntPtr dest,
ref uint destLen,
[In(), MarshalAs(UnmanagedType.LPArray)] byte[] source,
uint sourceLen
);
At runtime I check whether I'm 32-bit or 64-bit, and call appropriate version.
This works fine if I'm 32-bit, but the 64-bit version gives
Cannot load DLL "zlibwapi64.dll": Module not found. (HRESULT exception: 0x8007007E)
I've found many similar questions on the Internet, and the suggested reason was that the library depends on some other libraries, and it is those libraries that may not be found.
This does not seem to the case:
zlibwapi64.dll only depends on Kernel32.dll and MSVCR90.dll. I do have VS2008 C++ runtimes installed, both 32 and 64 bit.
When I try to load zlibwapi64.dll from a non-managed C++ application, it loads no problem. It is C# that fails to load it.
I have tried setting absolute path to the 64-bit dll, it does not help.
How do I make it work?
It is a fairly basic "file not found" kind of error, unfortunately it doesn't tell you explicitly what DLL it couldn't find. You already know about the issue with dependent DLLs. Note that you can avoid the irksome dependency on msvcr90.dll by compiling the code with /MT
You'll need to debug the problem and that requires getting insight in where it is looking for DLLs. One good tool is SysInternals' ProcMon utility, it shows you exactly where your program is looking for files. You should see it probing for the DLL, searching through the directories of the PATH and failing to find the file.
Unfortunately ProcMon is a bit chatty and has a habit of drowning you in the data. A more dedicated tool is GFlags.exe, a tool available from the Debugging Tools for Windows package. These days included with the Windows SDK. Stored in c:\program files (x86)\debugging tools for windows\gflags.exe after you installed it. You can turn on the "Show loader snaps" option. On later Windows versions, that tells the Windows loader to generate debugging messages when it is searching for DLLs. They'll appear in the Output window when you enable unmanaged debugging.
Try ProcMon first, much easier to get going.
And of course consider pure managed solutions so you are not fighting these kind of install problems. Good ones are DotNetZip and SharpZipLib, take their first google hit.
Another good tool for examining Dll dependencies is Dependency walker (depends). It looks at the file in a static way so a little easier than using process monitor.
http://www.dependencywalker.com/

Categories