Open programatix opened 4 years ago
@programatix FRDN depends on native binary and we take of architecture of binary. https://github.com/takuya-takeuchi/FaceRecognitionDotNet/wiki/Quickstart#windows
Is it possible to update the deployment script to include "any" which include both 32-bit and 64-bit runtimes? I have no idea.
If you need to build your app as AnyCpu (win-AnyCPU), eg user control issues when building as x64 and drag and drop in x32 IDE issues etc..
Create Folder win-AnyCPU like this:
%USERPROFILE%.nuget\packages\DlibDotNet.19.21.0.20210228\runtimes\win-AnyCPU
Then copy win-x64into win-AnyCPU folder- > builds then work as AnyCPU
%USERPROFILE%.nuget\packages\DlibDotNet.19.21.0.20210228\runtimes\win-x64
Note: Use Nuget Package Manager Console - Solution to reinstall current nuget packages if you switch DotNet Frameworks
Nuget Package Manager Console command to refresh nugets (reinstall for current framework)
Update-Package –reinstall
This is a batch file to assist with your missing AnyCPU
IF EXIST "C:\Users\%username%\.nuget\packages\dlibdotnet\19.21.0.20210228\runtimes\win-AnyCPU\" (
ECHO folder anyCPU already exists
) ELSE (
ECHO AnyCPU Foldlder does not exist, copying x64 to anyCPU
xcopy "C:\Users\%username%\.nuget\packages\dlibdotnet\19.21.0.20210228\runtimes\win-x64\" "C:\Users\%username%\.nuget\packages\dlibdotnet\19.21.0.20210228\runtimes\win-AnyCPU\" /E /I /Y )
I haven't tried this, but wouldn't this use the x64 native and it would have caused runtime error when running on a x86 machine, no?
I was thinking of having both the native binary of x86 and x64 referred in the FaceRecognitionDotNet DLL where when it refers to the native binary, it would choose which version to call during runtime.
Something like this,
#if __BUILD_BOTH__
#define __BUILD_32_BIT__
#define __BUILD_64_BIT__
#endif
//...
//...
{
static bool Is64bit = (IntPtr.Size == 8);
#if __BUILD_32_BIT__
[DllImport("NativeDll.x86.dll")]
static extern bool NativeFunction32(string in1, string in2);
#endif
#if __BUILD_64_BIT__
[DllImport("NativeDll.x64.dll")]
static extern bool NativeFunction64(string in1, string in2);
#endif
static bool NativeFunction(string in1, string in2)
{
if (Is64bit)
#if __BUILD_64_BIT__
return NativeFunction64(in1, in2);
#else
throw new Exception("Missing 64 bit native DLLs");
#endif
else
#if __BUILD_32_BIT__
return NativeFunction32(in1, in2);
#else
throw new Exception("Missing 32 bit native DLLs");
#endif
}
}
This way, FaceRecognitionDotNet can have 3 builds,
Hi programatix
There is a simple project demonstrating how to reference managed C++ functionality from a C# AnyCPU dll
Managed.AnyCPU https://github.com/kevin-marshall/Managed.AnyCPU
I believe the cleanest way to reference managed C++ functionality from a C# dll, compiled with the AnyCPU setting, is to create a C# front end to the C++ functionality.
In order for the C++ functionality to be consumed by a C# dll, the C++ project must produce both x86 and x64 versions of the dll. It is impossible to reference just a x86 or a x64 dll from a C# dll compiled with the AnyCPU setting.
Not trying to complain but this is getting more and more difficult to handle. Locally, there any many workarounds, but when used with Cloud Platforms like Azure DevOps, builds are failing when Target Platform is AnyCPU. AnyCPU is usually used because the build may be used on a x86 or x64 with a single build.
Perhaps we could refer to other projects such as https://github.com/dlemstra/Magick.NET which has similar dependency on native binaries. The AnyCPU release has both the x64 and x86 binaries.
I encountered HTTP Error 500.30 - ASP.NET Core app failed to start
issue when publishing Web App (Windows) in Azure. Turns out that the issue is due to the project build built as "x64". It seems to only be able to run when configured to "anyCPU".
At the server, this is the error when started from the command line,
Unhandled exception. System.BadImageFormatException: Could not load file or assembly 'C:\home\site\wwwroot\MyWebApp.dll'. An attempt was made to load a program with an incorrect format.
Update: Seems like the "platform" depends on the App Server Plan chosen. In my test environment case, turns out that it is "x86".
I have not checked Magck.NET code yet.
But nuget package has not special trick execept for *.targets
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<NativeDLL Include="$(MSBuildThisFileDirectory)\..\..\runtimes\**\*.dll" />
<Content Include="@(NativeDLL)">
<Link>%(FileName)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
Hi,
I noted 2 methods of "placing" the DLLs. In Magick.NET case, the DLLs are copied into the "runtimes" directory (using the nuget package directory structure). It doesn't show in Visual Studio Solution Explorer though.
In OpenCvSharp4 case, (it's OpenCvSharp4.runtime.xxx), it copied the DLLs in the following directory structure. Similar to the method you're using, the files are shown in Visual Studio Solution Explorer.
I think using nuget directory structure is better since I'm seeing many other packages are using this structure. On accessing the DLLs, I believe they should be using something as I mentioned above in https://github.com/takuya-takeuchi/FaceRecognitionDotNet/issues/114#issuecomment-781282012 where a wrapper function is used to call the native function in the correct DLL.
I know about opencv4 trick but it make package fat file. Especially, dlibdotnet.native.dnn is too large. To be honest, I think we should not take care of both x86 and x64. OSX and Linux has already abandoned x86. Face recognition modlel files consume not few memory so x86 can not put up with it.
Well, it would only make the AnyCPU package fat. Compared to other nuget packages, I think the files DlibDotNetNativeDnnAgeClassification.dll
and DlibDotNetNativeDnnGenderClassification.dll
in facerecognitiondotnet
are not big, no?
Also, the combination on DlibDotNetNative.dll
and DlibDotNetNativeDnn.dll
are about the size of a single Magick.NET native DLL.
For my case, I still need to use x86 because some devices I'm using only provide the x86 DLLs, such as the iris scanners and fingerprint scanners. Additionally AnyCPU apps are easier to deploy since it can be deployed on both x86 and x64 machines.
Oh, I forgot a acutual size of DlibDotNet. I talked about pacakge for android. And DlibDotNet (cpu binary) has already x86 and x64 binaries. So it may be easy to support any cpu.
BTW, Magick.NET trick is available in .NET framework?
Magick.NET nuget packages are
So it covered both .NET Framework and .NET Core. I just realized that if you go this route, you'll have to publish at least 2 nuget packages.
Hi,
I'm using the nuget package and if I configure my project to "any" platform, it will fail to build with the error message,
Is it possible to update the deployment script to include "any" which include both 32-bit and 64-bit runtimes?