DllNotFoundException in unity3d plugin for c++ dll - unity3d

I am working on the Unity Plugin project and try to import the c++ native dll from c# file.
But I keep getting dllnotfoundexception.
c++ dll code:
extern "C" {
extern __declspec( dllexport ) bool IGP_IsActivated();
}
c# code:
[DllImport("mydll")]
private static extern bool IGP_IsActivated();
Dll is in place and FIle.Exists work properly. All dependent dlls are present at same hierarchy, but I still end up in dllnotfound exception.
Any help, much appreciated!!

Thanks to this Unity forum post I came up with a nice solution which modifies the PATH-environment variable at runtime:
Put all DLLs (both the DLLs which Unity interfaces with and their dependent DLLs) in Project\Assets\Wherever\Works\Best\Plugins.
Put the following static constructor into a class which uses the plugin:
static MyClassWhichUsesPlugin() // static Constructor
{
var currentPath = Environment.GetEnvironmentVariable("PATH",
EnvironmentVariableTarget.Process);
#if UNITY_EDITOR_32
var dllPath = Application.dataPath
+ Path.DirectorySeparatorChar + "SomePath"
+ Path.DirectorySeparatorChar + "Plugins"
+ Path.DirectorySeparatorChar + "x86";
#elif UNITY_EDITOR_64
var dllPath = Application.dataPath
+ Path.DirectorySeparatorChar + "SomePath"
+ Path.DirectorySeparatorChar + "Plugins"
+ Path.DirectorySeparatorChar + "x86_64";
#else // Player
var dllPath = Application.dataPath
+ Path.DirectorySeparatorChar + "Plugins";
#endif
if (currentPath != null && currentPath.Contains(dllPath) == false)
Environment.SetEnvironmentVariable("PATH", currentPath + Path.PathSeparator
+ dllPath, EnvironmentVariableTarget.Process);
}
Add [InitializeOnLoad] to the class to make sure that the constructor is run at editor launch:
[InitializeOnLoad]
public class MyClassWhichUsesPlugin
{
...
static MyClassWhichUsesPlugin() // static Constructor
{
...
}
}
With this script there is no need to copy around DLLs. The Unity editor finds them in the Assets/.../Plugins/...-folder and the executable finds them in ..._Data/Plugins-directory (where they get automatically copied when building).

Well I got it working.
For others who may face this problem, if you have more than one dll, you need to put the secondary dlls at root level of the Unity editor (e.g. C:\Program Files\Unity\Editor) and the actual referenced dll from script into plugins folder.
This worked for me.

Put the DLL(s) Unity interfaces with in Project\Assets\Wherever\Works\Best\Plugins.
Place any dependency DLLs that are not directly accessed by your scripts in Project. This will allow your program to run in the editor.
When you build, again copy the dependency DLL files, this time to the root of the build directory (right next to the generated executable). This should allow your application to load them at runtime.
(Tip: you can use Dependency Walker look at you DLLs and see what they depends on.)

I spent one day with this error. My issue was that Android doesn't get the library and always get and DDLNotFound error. My solution was:
1.- Be sure that you have the libraries for the proper architecture in the Plugins folder.
Plugins/Android/x86 and Plugins/Android/armeabi-v7a if your build settings is FAT(x86&arm)
2.- Check that Unity recognizes them as libraries. If you select them in the Project tab you should see them as a library and the platform and architecture related.
3.- After the build (don't close Unity Editor!), you can check in the Temp/StagingArea/libs if your libraries are there. If there are there for sure the libraries are going to be in the APK. As a double check, you can open your APK (change to zip extension) and see the libraries in the lib folder.
4.- In C# you should remove any lib prefix in your library name, for example:
If your library name is "libdosomething.so" you should call it as
[DllImport ("dosomething")]
I hope this work for you :)
Cheers.

Make sure the following chacklist is satisfied:
Plugins should all stay in a folder called Plugins.
The architecture your dll is built for (x86 or x86_64) must correspond to the architecture version of Unity Editor. Unity Editor 32-bit will not load 64 bit plugins and viceversa.
If you are targeting both 32 and 64 bit architectures you should put your dlls in special named folders inside the Plugins folder. The names are Plugins/x86 for 32 bit dlls and Plugins/x86_64 (x64 also works) for 64 bit dlls.
Visual C++ Redistributables must be installed. I have all from 2008.
When you build all your dlls should be copied into the root where your executable is (and again built for the correct x86/x64 architecture)
If you keep getting a namespace error it means the dll you are importing has unmanaged code and it must be wrapped into another managed dll Pugin in order to work.
These threads are a bit outdated but still relevant
DLLNotFoundException - Unity3D Plugin
Unity internal compiler error with custom dll

In my case, I have DllNotFoundException: ovrplatiformloader
Unity : DllNotFoundException: ovrplatformloader
Unity : at (wrapper managed-to-native) Oculus.Platform.CAPI.ovr_UnityInitWrapperAsynchronous(string)
Unity : at Oculus.Platform.AndroidPlatform.AsyncInitialize (System.String appId) [0x00013] in <29065e843b82403894fca6c6f2974090>:0
Unity : at Oculus.Platform.Core.AsyncInitialize (System.String appId) [0x0004f] in <29065e843b82403894fca6c6f2974090>:0
Unity : at DBHelper.Start () [0x00019] in <29065e843b82403894fca6c6f2974090>:0
My solution is:
Re-import files that doesn't work (libovrplatformloader.so)
Reconstruct the Platform/Plugins architecture. Old: Platform/Plugins/Android32/libovrplatformloader.so. New: Platform/Plugins/Android/x86/libovrplatformloader.so and Platform/Plugins/Android/armeabi-v7a/libovrplatformloader.so
Modify the import setting of libovrplatformloader.so. Change any platform to only Android platform and enable 'load on startup' selection. Choose ARMv7 CPU in armeabit-v7a while choose x86 CPU in x86 folder.

just put the dlls under Plugins folder and that works for me

I was having the same issue, and the solutions described here didn't work.
I think my case was a little different.
I think that the .dll I was importing depended on other .dll files. So I imported the other files related to that .dll (which I thought were unnecessary since I am not calling them directly on c# code) and that solved the issue.

Related

Flutter windows: can I use relative path to bundle `.dll` library in CMakeLists.txt?

I am building a flutter plugin which calls native functions from lib.dll file and everything works as expected in my computer.
But I use relative path to link that lib such as
E:/_Projects/mahesabu/client/packages/server/windows/lib.dll
Now I want to move the build process in CI/CD which I believe using relative path such as
./lib.dll would be very easy.
Of cource I am new to cmake configuration. And in one comment it is written
List of absolute paths to libraries that should be bundled with the plugin
I wonder how can I use relative path there, because if I try build fails. The following is CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
set(PROJECT_NAME "server")
project(${PROJECT_NAME} LANGUAGES CXX)
# This value is used when generating builds using this plugin, so it must
# not be changed
set(PLUGIN_NAME "server_plugin")
add_library(${PLUGIN_NAME} SHARED
"server_plugin.cpp"
)
apply_standard_settings(${PLUGIN_NAME})
set_target_properties(${PLUGIN_NAME} PROPERTIES
CXX_VISIBILITY_PRESET hidden)
target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL)
target_include_directories(${PLUGIN_NAME} INTERFACE
"${CMAKE_CURRENT_SOURCE_DIR}/include")
target_link_libraries(${PLUGIN_NAME} PRIVATE flutter flutter_wrapper_plugin)
# List of absolute paths to libraries that should be bundled with the plugin
set(server_bundled_libraries
""
"E:/_Projects/mahesabu/client/packages/server/windows/lib.dll" #USE RELATIVE PATH HERE
PARENT_SCOPE
)
Any help will be appreciated.
Just use:
set(server_bundled_libraries "${CMAKE_CURRENT_SOURCE_DIR}/lib.dll" PARENT_SCOPE)
The CMAKE_CURRENT_SOURCE_DIR variable will expand to current source directory as tracked by add_subdirectory. This is usually, but not always, the directory in which the present CMakeLists.txt resides. Presumably, this is E:/_Projects/mahesabu/client/packages/server/windows on your computer (given your remark that you expect ./lib.dll to work), but will be somewhere else on CI or elsewhere.

Using ZXing with Hololens

I've been trying to use Zxing on the Hololens but as soon as the app starts on the device, I get a fileloadException when this line is called:
BarcodeReader barcodeReader = new BarcodeReader();
FileLoadException: Could not load file or assembly 'System.Core,
Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
The located assembly's manifest definition does not match the assembly
reference. (Exception from HRESULT: 0x80131040) at
ZXing.BarcodeReader..ctor() at Decoder.Start() at
Decoder.$Invoke1(Int64 instance, Int64 args) at
UnityEngine.Internal.$MethodUtility.InvokeMethod(Int64 instance, Int64
args, IntPtr method) (Filename: Line: 0).
I have the Unity 2018.1.0b5 beta version with Visual Studio 2017 on Windows 10.
The Building works perfectly so the library is found.
Here's how I import ZXing library :
I've read all the other topics I found on it but the solutions provided do not work. I also tried to use the Zxing.winmd but the dll can't be found then.
Did I miss a step ? A file to download maybe ?
Thanks for your help !
After many configurations tried, I finally managed to use Zxing on Hololens by switching the scripting Backend in Player Settings to Il2Cpp. I was using .net (for the scripting backend) which caused me most of the errors. Il2CPP
If you don't have the IlCPP proposition, you might need to relaunch the Unity installer, making sure that "Windows Store Il2CPP " is checked.installation
I also downgraded my version of unity to 2017 in order to use the Holotoolkit which wasn't working on my 2018 beta version.
This way I don't need any specific settings to import Zxing in the Assets. Also, I didn't use Zxing.winmd but Zxing.unity.
settings Zxing
Tips : don't forget to unable the webcam and to deploy it in Visual Studio with "Release", otherwise it's going to slow down your app.
If Visual Studio doesn't find your Zxing.unity file, right click on your project in the Solution's Explorer (of Visual Studio) : Add->Reference->Find your Zxing.unity.

Renaming sub package names in my Android project

I have an Android project called my.android.project, and in my src directory, I have a few sub-packages called my.android.projectGUI, my.android.projectClasses, my.android.projectOthers.
I wish to change my package name to com.android.project instead. I have successfully done this with Android Tools->Rename Application Package. However, this didn't take care of my sub packages in my src directory. I wish to rename them to com.android.project.gui, com.android.project.classes, and com.android.project.others
In my.android.projectOthers, I have a java file AccessJNI.java that loads a JNI library that is linked to jni/myjnifiles/myjni.c
When I try to change the sub-packages individually via Refactor->Rename, it works for the all except for my.android.projectOthers. Once I rename this sub-package, Eclipse throws me an error for several JNI symbols, saying they could not be resolved. This happens despite me changing all JNI function calls in myjni.c from Java_my_android_projectOthers_AccessJNI_functionName() to Java_com_android_project.others_AccessJNI_functionName()
The strange thing is, ndk-build still builds the library correctly, but Eclipse cannot seem to resolve the JNI symbols.
Am I missing anything while renaming my sub-packages?
Thanks!
This happens despite me changing all JNI function calls in myjni.c from Java_my_android_projectOthers_AccessJNI_functionName() to Java_com_android_project.others_AccessJNI_functionName()
You should replace all JNI prefixes by Java_com_android_project_others_ and not Java_com_android_project.others_

Compiling & sharing static iPhone library -- issue

I am facing a strange issue while compiling my own static library. My library is referring to some other libs and hence in my Target build settings I have give "Library Search Path" to these libs. Now, when I compile and share this static lib & other libs which my static lib needs with other project it fails on compilation as it tend to search for these libs in the path I specified when building the static lib.
If I remove the "Library Search Path" contents while compiling my static lib, it fails at compilation time. I am totally stuck here.
ALong with setting up Header Search Path , Try setting up the Other Linkers Flag too..
Go to “Other Linker Flags” under the “Linker” section, and add “-ObjC” and “-all_load” to the list of flags
Hope that works for you,

What is the difference between building C++ Builder project from IDE and command line?

I have different behaviour of compiler, when building project from IDE and from command-line, which I can not explain.
The detailed issue's description is rather big, but it's really simple.
I have a C++ Builder project, which has a PAS-file included (IncludeUnits.pas). This pas-file has several units and inc-files listed. These files are located in separate folders and these folders are listed in library&include paths in project's options.
Folders layout:
C:\Demo\Bin
C:\Demo\Project
C:\Demo\Project\CBuilder5
C:\Demo\Project\Common
C:\Demo\Source
C:\Demo\Source\Common
Bin is output folder, Project/CBuilder5 holds project (bpr-file), Project/Common holds included pas-file (IncludeUnits.pas), Source and Source/Common hold other files (pas&inc). I think that it's pretty usual layout.
C:\Demo\Project\Common\ IncludeUnits.pas :
unit IncludeUnits;
interface
uses
Test;
implementation
end.
C:\Demo\Source\ Test.pas :
unit Test;
interface
{$I Test.inc}
implementation
end.
C:\Demo\Source\Common\ Test.inc :
// this file is empty
If I compile this project from C++ Builder IDE - it will compile fine. C++ Builder IDE doesn't have any additional paths in IDE settings set.
Now, I want to compile it from command-line. First, I issue
bpr2mak.exe MyProject.bpr
command.
This command creates MyProject.mak file, where I can see all paths ("....\Source" and "....\Source\Common" are the paths in question):
...
INCLUDEPATH = $(BCB)\include;$(BCB)\include\vcl;..\Common;..\..\Source;..\..\Source\Common
LIBPATH = $(BCB)\lib\obj;$(BCB)\lib;..\Common;..\..\Source;..\..\Source\Common
...
Now, I run make command:
make.exe -B -f"MyProject.mak"
It gives me the following output:
C:\PROGRA~1\Borland\CBUILD~2\BIN\dcc32 -N2....\Bin -N0....\Bin -$Y+ -$W -$R -v -JPHNE -M -UC:\PROGRA~1\Borland\CBUILD~2\bin..\include;C:\PROGRA~1\Borland\CBUILD~2\bin..\include\vcl;..\Common;..\..\Source;..\..\Source\Common -D_DEBUG;_RTLDLL;NO_STRICT -OC:\PROGRA~1\Borland\CBUILD~2\bin..\include;C:\PROGRA~1\Borland\CBUILD~2\bin..\include\vcl;..\Common;..\..\Source;..\..\Source\Common --BCB ..\Common\IncludeUnits.PAS
Borland Delphi Version 13.0 Copyright (c) 1983,99 Inprise Corporation
C:\Demo\Project\Common\IncludeUnits.pas(1) C:\Demo\Project\Common\IncludeUnits.pas(1) C:\Demo\Project\Common\IncludeUnits.pas(1) C:\Demo\Project\Common\IncludeUnits.pas(6) C:\Demo\Source\Test.pas(1) C:\Demo\Source\Test.pas(5) Fatal: File not found: 'Test.inc'
As you can see - all search path is passed to compiler and the file (Test.inc) is all here - in that Source\Common folder. But still compiler can't find it?
Of course, I run both commands from folder with bpr-file. And changing paths to absolute doesn't help.
Copying Test.inc from Source\Common to Source will help. Changing {$I Test.inc} to {$I Common\Test.inc} will also help.
Why? It seems that I'm missing something. Remember: project have no problems with compiling from IDE, Test.inc is found without copying or changing declaration. Did I miss some switch to make or dcc32?
I found the reason: command line for dcc32 misses -I switch, which specifies paths for include files.
For some reason, bpr2mak doesn't respect this option. Fortunately, it allows you to specify alternate template for conversion bpr -> mak. I edited default template and added "-I" option to it, pass new template to bpr2mak - and it worked.