Thursday 22 October 2020

Unity C# how to load a managed DLL properly?

Based on this other question from here Using OpenH264 DLL in C# Project I'm basically trying to use the library https://github.com/secile/OpenH264Lib.NET in unity to encode H264 video files in real time, using unity's JINT native library for use in JavaScript interperting

I am having quite a bit of difficulty referencing the DLL in unity though.

I follow the instructions from the GitHub site and manage to compile to OPenH264Lib.dll (as well as the sample project, and get the sample project to work with visual studio 2019, on windows x64 fine, and it encodes everything etc), but when I simply drag the compiled OpenH264Lib.dll to the Plugins folder in the Assets folder of a Unity project, I am not able to access the namespace OpenH264Lib, which is used in the standard C# sample there to access the DLL managed functions, it just says in the unity console the namespace isn't found.

OK fine so I decided to build a C# DLL with visual studio, which itself loads in OpenH264Lib.dll and then call its functions from there, then use the C# DLL in unity, so here's my C# code in visuaal studio (after having put the compiled (with .NET version 4.6.1) OpenH264Lib.dll in the Debug folder, just like in the sample, and I'm not getting any reference errors in Visual Studio 2019):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Sayfir
{
    public class Class1
    {
        public static OpenH264Lib.Encoder ok(string path)
        {
            var code = new OpenH264Lib.Encoder(path);
            return code;
        }
    }
}

OK fine so this builds perfectly with no errors and it seems to be doing the same as the sample folder (in Assets/Plugins).

Then when I take the DLL files generated in the x64/Debug folder of my solution (both the OpenH264Lib.dll and the Sayfir.dll) and copy them to the Plugins folder in Unity, then try to access it in unity like so

public class Yetzirah {
        public static void Wellz() {
            var k = Sayfir.Class1.ok("2");
            Debug.Log(k);
        }
}

I get an error in the Unity console

Assets\scripts\Yetzirah.cs(45,12): error CS0012: The type 'Encoder' is defined in an assembly that is not referenced. You must add a reference to assembly 'OpenH264Lib, Version=1.0.7598.38705, Culture=neutral, PublicKeyToken=null'.

so it seems it recognizes the Sayfir.dll file compiled from the source above, but just not the OpenH264Lib.dll that it depends on, even though both are in the same folder (in Assets/Plugins)

I've heard about .rsp files but I tried making one with the name csc.rsp and adding it to Assets with the content -r:OpenH264Lib

still nothing

Also I've heard of .asmdef files but when I made one with the contents

{
    "references":  "OpenH264Lib" 
}

But still nothing, I don't really know much about asmdef files, I also don't know much about this error or in general how to use managed C++ DLLs in unity at all.

I've also seen an article that mentions referencing external DLL files in unity, but it says to go to

Project > Edit References > .NET Assembly

Thing is, I don't know how to get to that screen in the UnityEditor 2020, or if there is even a way to get there or accomplish the same thing, if so I don't know how and wasn't able to find it searching

I tried making another DLL using standard dllexports, with the header file contents of

extern "C" __declspec(dllexport) int well();

then in the .cpp file

#include "deeall.h"
__declspec(dllexport) int well() {
    return 634;
}

then in unity C#

DllImport("deeall.dll", EntryPoint="well")]
public static extern int well();

then it works, but when I include in the dll extern int any kinds of managed libraries i get an error __declspec(dllexport) cannot be applied to a function with the __clrcall calling convention.

which is what is necessary if I want to use __declspec exports for the C# wrapper

As a hack I tried adding to the Encoder.cpp file itself (from the source of the OpenH264Lib .dll) the following

    __declspec(dllexport) int well() {
        String ^h = "ok";
        Encoder
        ^enc = 
        gcnew Encoder(
            h
        );
        return 4;
    }

trying to call the Encoder function directly, (along with the following header file modification to Encoder.h:

namespace OpenH264Lib {
    extern "C" __declspec(dllexport) int well();
    //etc.. rest of code in namespace.....

) then in unity

[DllImport("OpenH264Lib6.dll", EntryPoint="well")]
public static extern int well();

but when I called well(), unity hung for a while then crashed, without any errors

So how can I get the OpenH264Lib.dll working in unity, or other similar managed compiled C++ DLLs in unity? If this is not possible is there any other way I can use OpenH264 in general in Unity? If not are there any others solutions for encoding H264 videos in real time in unity (from byte[]s)?



from Unity C# how to load a managed DLL properly?

No comments:

Post a Comment