c#调用C++ dll 报未将对象引用到设置对象的实例 的解决方案

    xiaoxiao2024-04-18  5

    c# 调用 C++ dll 第一次调用的时候,可以正常加载,正常返回,多次调用之后在执行完 sendMessage(b); 之后,就会报 未将对象引用到设置对象的实例,代码如下: using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using System.Windows.Forms; using System.Runtime.InteropServices; namespace CSharpDemo { class Program { [DllImport("kernel32.dll", EntryPoint = "LoadLibrary", SetLastError = true)] public static extern IntPtr LoadLibrary( [MarshalAs(UnmanagedType.LPStr)] string lpLibFileName); [DllImport("kernel32.dll", EntryPoint = "GetProcAddress", SetLastError = true)] public static extern IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)] string lpProcName); [DllImport("kernel32.dll", EntryPoint = "FreeLibrary")] public static extern bool FreeLibrary(IntPtr hModule); public delegate int InitPrinterManager(); public delegate void _onMessage_func(IntPtr str); public delegate void SetRecvDataCallback(_onMessage_func callback); public delegate int SendMessage(byte[] str); public delegate int ClosePrinterManager(); public static IntPtr hLib; public static SendMessage sendMessage; static void onMessage(IntPtr str) { byte[] buffer1 = Encoding.Default.GetBytes(Marshal.PtrToStringAnsi(str)); byte[] buffer2 = Encoding.Convert(Encoding.UTF8, Encoding.Default, buffer1, 0, buffer1.Length); string strBuffer = Encoding.Default.GetString(buffer2, 0, buffer2.Length); } static void WebSocket() { string str = "{\"cmd\":\"print\",\"requestID\":\"123458976\",\"version\":\"1.0\"}"; byte[] b = System.Text.Encoding.UTF8.GetBytes(str); //用于接口返回 int Res = -1; //IntPtr hLib; //以下动态载入dll库 if (hLib == IntPtr.Zero) { if (IntPtr.Size == 8) //判断版本号 hLib = LoadLibrary("PrinterManager64.dll"); else hLib = LoadLibrary("PrinterManager32.dll"); if (hLib == IntPtr.Zero) { Console.WriteLine("loadlibrary failed! ErrorNuber:" + Marshal.GetLastWin32Error().ToString()); System.Threading.Thread.Sleep(2000); System.Environment.Exit(-1); } //以下载入初始化函数initPrinterManager IntPtr hapi = GetProcAddress(hLib, "initPrinterManager"); if (hapi == IntPtr.Zero) { Console.WriteLine("load initPrinterManager failed! ErrorNuber:" + Marshal.GetLastWin32Error().ToString()); System.Threading.Thread.Sleep(2000); System.Environment.Exit(-1); } //将初始化函数指针封装成委托,并调用 InitPrinterManager initPrinterManager = (InitPrinterManager)Marshal.GetDelegateForFunctionPointer(hapi, typeof(InitPrinterManager)); Res = initPrinterManager(); if (Res != 0) { Console.WriteLine("run initPrinterManager failed! \n"); System.Threading.Thread.Sleep(2000); System.Environment.Exit(-1); } //以下载入设定回调函数的函数,并调用 IntPtr hapi2 = GetProcAddress(hLib, "setRecvDataCallback"); if (hapi2 == IntPtr.Zero) { Console.WriteLine("load setRecvDataCallback failed! ErrorNuber:" + Marshal.GetLastWin32Error().ToString()); } SetRecvDataCallback setRecvDataCallback = (SetRecvDataCallback)Marshal.GetDelegateForFunctionPointer(hapi2, typeof(SetRecvDataCallback)); setRecvDataCallback(onMessage); IntPtr hapi3 = GetProcAddress(hLib, "sendMessage"); if (hapi3 == IntPtr.Zero) { Console.WriteLine("load sendMessage failed! ErrorNuber:" + Marshal.GetLastWin32Error().ToString()); } sendMessage = (SendMessage)Marshal.GetDelegateForFunctionPointer(hapi3, typeof(SendMessage)); Res = sendMessage(b); if (Res != 0) { Console.WriteLine("sendMessage failed! \n"); System.Threading.Thread.Sleep(2000); System.Environment.Exit(-1); } System.Threading.Thread.Sleep(1000); } else { Res = sendMessage(b); if (Res != 0) { Console.WriteLine("sendMessage failed! \n"); System.Threading.Thread.Sleep(2000); System.Environment.Exit(-1); } System.Threading.Thread.Sleep(1000); } } public void Close() { int Res = -1; //以下载入关闭连接函数,并调用 IntPtr hapi4 = GetProcAddress(hLib, "closePrinterManager"); if (hapi4 == IntPtr.Zero) { Console.WriteLine("load closePrinterManager failed! ErrorNuber:" + Marshal.GetLastWin32Error().ToString()); } ClosePrinterManager closePrinterManager = (ClosePrinterManager)Marshal.GetDelegateForFunctionPointer(hapi4, typeof(ClosePrinterManager)); Res = closePrinterManager(); if (Res != 0) { Console.WriteLine("closePrinterManager failed! \n"); System.Threading.Thread.Sleep(2000); System.Environment.Exit(-1); } //释放动态链接库 FreeLibrary(hLib); Console.Read(); } } } 查找原因发现回调函数需要声明一个静态对象来存储,改成以下之后,可以正常调用 using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; namespace CSharpDemo { class CSharpDemo { [UnmanagedFunctionPointer(CallingConvention.StdCall)] public delegate void WriteToConsoleCallback(IntPtr str); [DllImport("kernel32.dll", EntryPoint = "LoadLibrary", SetLastError = true)] public static extern IntPtr LoadLibrary( [MarshalAs(UnmanagedType.LPStr)] string lpLibFileName); [DllImport("kernel32.dll", EntryPoint = "GetProcAddress", SetLastError = true)] public static extern IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)] string lpProcName); [DllImport("kernel32.dll", EntryPoint = "FreeLibrary")] public static extern bool FreeLibrary(IntPtr hModule); public delegate int InitPrinterManager(); //public delegate void _onMessage_func(IntPtr str); //public delegate void SetRecvDataCallback(_onMessage_func callback); public delegate void SetRecvDataCallback(WriteToConsoleCallback callback); public delegate int SendMessage(byte[] str); public delegate int ClosePrinterManager(); private static WriteToConsoleCallback callback; public static string strMessage = ""; public static IntPtr hLib; public static SendMessage sendMessage; //回调函数 static void onMessage(IntPtr str) { byte[] buffer1 = Encoding.Default.GetBytes(Marshal.PtrToStringAnsi(str)); byte[] buffer2 = Encoding.Convert(Encoding.UTF8, Encoding.Default, buffer1, 0, buffer1.Length); string strBuffer = Encoding.Default.GetString(buffer2, 0, buffer2.Length); } /// <summary> /// 连接 /// </summary> public static void Websocket() { try { //以下载入发送数据函数,并发送数据 string str = "{\"cmd\":\"print\",\"requestID\":\"123458976\",\"version\":\"1.0\"}"; byte[] b = System.Text.Encoding.UTF8.GetBytes(str); //用于接口返回 int Res = -1; //IntPtr hLib; //以下动态载入dll库 if (hLib == IntPtr.Zero) { if (IntPtr.Size == 8) hLib = LoadLibrary("PrinterManager64.dll"); else hLib = LoadLibrary("PrinterManager32.dll"); if (hLib == IntPtr.Zero) { Console.WriteLine("loadlibrary failed! ErrorNuber:" + Marshal.GetLastWin32Error().ToString()); System.Threading.Thread.Sleep(2000); System.Environment.Exit(-1); } //以下载入初始化函数initPrinterManager IntPtr hapi = GetProcAddress(hLib, "initPrinterManager"); if (hapi == IntPtr.Zero) { Console.WriteLine("load initPrinterManager failed! ErrorNuber:" + Marshal.GetLastWin32Error().ToString()); System.Threading.Thread.Sleep(2000); System.Environment.Exit(-1); } //将初始化函数指针封装成委托,并调用 InitPrinterManager initPrinterManager = (InitPrinterManager)Marshal.GetDelegateForFunctionPointer(hapi, typeof(InitPrinterManager)); Res = initPrinterManager(); if (Res != 0) { Console.WriteLine("run initPrinterManager failed! \n"); System.Threading.Thread.Sleep(2000); System.Environment.Exit(-1); } //以下载入设定回调函数的函数,并调用 IntPtr hapi2 = GetProcAddress(hLib, "setRecvDataCallback"); if (hapi2 == IntPtr.Zero) { Console.WriteLine("load setRecvDataCallback failed! ErrorNuber:" + Marshal.GetLastWin32Error().ToString()); } SetRecvDataCallback setRecvDataCallback = (SetRecvDataCallback)Marshal.GetDelegateForFunctionPointer(hapi2, typeof(SetRecvDataCallback)); //setRecvDataCallback(onMessage); //setRecvDataCallback(null); callback = new WriteToConsoleCallback(onMessage); setRecvDataCallback(callback); IntPtr hapi3 = GetProcAddress(hLib, "sendMessage"); if (hapi3 == IntPtr.Zero) { Console.WriteLine("load sendMessage failed! ErrorNuber:" + Marshal.GetLastWin32Error().ToString()); } sendMessage = (SendMessage)Marshal.GetDelegateForFunctionPointer(hapi3, typeof(SendMessage)); Res = sendMessage(b); if (Res != 0) { Console.WriteLine("sendMessage failed! \n"); System.Threading.Thread.Sleep(2000); System.Environment.Exit(-1); } System.Threading.Thread.Sleep(1000); } else { Res = sendMessage(b); if (Res != 0) { Console.WriteLine("sendMessage failed! \n"); System.Threading.Thread.Sleep(2000); System.Environment.Exit(-1); } System.Threading.Thread.Sleep(1000); } } catch (Exception ex) { } } /// <summary> /// 关闭关闭连接函数 /// </summary> public void Close() { int Res = -1; //以下载入关闭连接函数,并调用 IntPtr hapi4 = GetProcAddress(hLib, "closePrinterManager"); if (hapi4 == IntPtr.Zero) { Console.WriteLine("load closePrinterManager failed! ErrorNuber:" + Marshal.GetLastWin32Error().ToString()); } ClosePrinterManager closePrinterManager = (ClosePrinterManager)Marshal.GetDelegateForFunctionPointer(hapi4, typeof(ClosePrinterManager)); Res = closePrinterManager(); if (Res != 0) { Console.WriteLine("closePrinterManager failed! \n"); System.Threading.Thread.Sleep(2000); System.Environment.Exit(-1); } //释放动态链接库 FreeLibrary(hLib); } } }
    转载请注明原文地址: https://ju.6miu.com/read-1288107.html
    最新回复(0)