Maicon
Maicon

Reputation: 51

Load Native AOT C# dll with extern

I have a C# DLL that I am compiling to Native AOT. The content of the DLL is as follows:

namespace teste
{    
    public class Principal 
    {
        public Principal()
        {
        }

        public void WriteTest() {
            System.IO.File.WriteAllText("c:\test.txt","blablablbalba");
        }
    }
}

I want to load this DLL from another project, a regular console project, and call the WriteTest() method. This new project is not Native AOT. I tried the following approach, but it was unsuccessful:

public class StartTest
{

[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern IntPtr LoadLibrary(string lpFileName);

[DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);

[DllImport("kernel32.dll")]
static extern bool FreeLibrary(IntPtr hModule);

delegate void CreateInstanceDelegate(IntPtr instance);
delegate void GravaTesteDelegate(IntPtr instance);

public static void Main(string[] args)
{
    try
    {
//loaded successfully
        var hModule = LoadLibrary("testeload.dll");

//find null address ctor here
        IntPtr pFunc = GetProcAddress(hModule, "teste.Principal..ctor");

        IntPtr pInstance = Marshal.AllocHGlobal(IntPtr.Size);
        Marshal.WriteIntPtr(pInstance, IntPtr.Zero);
        Marshal.GetDelegateForFunctionPointer<CreateInstanceDelegate>(pFunc)(pInstance);

        IntPtr pMethod = GetProcAddress(hModule, "teste.Principal.WriteTest");

        Marshal.GetDelegateForFunctionPointer<GravaTesteDelegate>(pMethod)(pInstance);

        Marshal.FreeHGlobal(pInstance);
        FreeLibrary(hModule);
    }
    catch (Exception ex)
    {

        throw ex;
    }

}
}

Upvotes: -1

Views: 1077

Answers (1)

Maicon
Maicon

Reputation: 51

with help from @Hans Passant i was able to solve it with below code for strings

  [UnmanagedCallersOnly(EntryPoint = "writetest")]
        public static IntPtr writetest(IntPtr argum) {

            string str = Marshal.PtrToStringAnsi(argum);

            Console.WriteLine(str);
            
            return Marshal.StringToHGlobalAnsi(str + "mudou");
        }

if anyone knows a more elegant way to solve it, feel free to post

Upvotes: -1

Related Questions