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