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

本文主要是介绍c#调用C++ dll 报未将对象引用到设置对象的实例 的解决方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


PS: 我遇到的问题和这个情况类似。


提炼核心语句:


public delegate void WriteToConsoleCallback(IntPtr str); private static WriteToConsoleCallback callback; callback = new WriteToConsoleCallback(onMessage);  
setRecvDataCallback(callback);   //setRecvDataCallback 是DLL导出函数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);  
}  




来源:http://blog.csdn.net/likang6/article/details/52191606


c# 调用 C++ dll 第一次调用的时候,可以正常加载正常返回,多次调用之后在执行完 sendMessage(b); 之后,就会报 未将对象引用到设置对象的实例,代码如下

[csharp]  view plain  copy
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4. using System.Runtime.InteropServices;  
  5. using System.Windows.Forms;  
  6. using System.Runtime.InteropServices;  
  7.   
  8. namespace CSharpDemo  
  9. {  
  10.     class Program  
  11.     {  
  12.         [DllImport("kernel32.dll", EntryPoint = "LoadLibrary", SetLastError = true)]  
  13.         public static extern IntPtr LoadLibrary(  
  14.            [MarshalAs(UnmanagedType.LPStr)] string lpLibFileName);  
  15.   
  16.         [DllImport("kernel32.dll", EntryPoint = "GetProcAddress", SetLastError = true)]  
  17.         public static extern IntPtr GetProcAddress(IntPtr hModule,  
  18.                    [MarshalAs(UnmanagedType.LPStr)] string lpProcName);  
  19.   
  20.         [DllImport("kernel32.dll", EntryPoint = "FreeLibrary")]  
  21.         public static extern bool FreeLibrary(IntPtr hModule);  
  22.   
  23.   
  24.         public delegate int InitPrinterManager();  
  25.         public delegate void _onMessage_func(IntPtr str);  
  26.         public delegate void SetRecvDataCallback(_onMessage_func callback);  
  27.         public delegate int SendMessage(byte[] str);  
  28.         public delegate int ClosePrinterManager();  
  29.   
  30.         public static IntPtr hLib;  
  31.         public static SendMessage sendMessage;  
  32.         static void onMessage(IntPtr str)  
  33.         {  
  34.   
  35.             byte[] buffer1 = Encoding.Default.GetBytes(Marshal.PtrToStringAnsi(str));  
  36.             byte[] buffer2 = Encoding.Convert(Encoding.UTF8, Encoding.Default, buffer1, 0, buffer1.Length);  
  37.             string strBuffer = Encoding.Default.GetString(buffer2, 0, buffer2.Length);  
  38.   
  39.   
  40.         }  
  41.         static void WebSocket()  
  42.         {  
  43.   
  44.   
  45.             string str = "{\"cmd\":\"print\",\"requestID\":\"123458976\",\"version\":\"1.0\"}";  
  46.   
  47.             byte[] b = System.Text.Encoding.UTF8.GetBytes(str);  
  48.   
  49.   
  50.             //用于接口返回  
  51.             int Res = -1;  
  52.             //IntPtr hLib;  
  53.             //以下动态载入dll库  
  54.             if (hLib == IntPtr.Zero)  
  55.             {  
  56.                 if (IntPtr.Size == 8)  //判断版本号  
  57.                     hLib = LoadLibrary("PrinterManager64.dll");  
  58.                 else  
  59.                     hLib = LoadLibrary("PrinterManager32.dll");  
  60.   
  61.   
  62.                 if (hLib == IntPtr.Zero)  
  63.                 {  
  64.   
  65.                     Console.WriteLine("loadlibrary failed! ErrorNuber:" + Marshal.GetLastWin32Error().ToString());  
  66.                     System.Threading.Thread.Sleep(2000);  
  67.                     System.Environment.Exit(-1);  
  68.                 }  
  69.                 //以下载入初始化函数initPrinterManager  
  70.                 IntPtr hapi = GetProcAddress(hLib, "initPrinterManager");  
  71.                 if (hapi == IntPtr.Zero)  
  72.                 {  
  73.                     Console.WriteLine("load initPrinterManager failed! ErrorNuber:" + Marshal.GetLastWin32Error().ToString());  
  74.                     System.Threading.Thread.Sleep(2000);  
  75.                     System.Environment.Exit(-1);  
  76.                 }  
  77.                 //将初始化函数指针封装成委托,并调用  
  78.                 InitPrinterManager initPrinterManager =  
  79.                     (InitPrinterManager)Marshal.GetDelegateForFunctionPointer(hapi, typeof(InitPrinterManager));  
  80.                 Res = initPrinterManager();  
  81.                 if (Res != 0)  
  82.                 {  
  83.                     Console.WriteLine("run initPrinterManager failed! \n");  
  84.                     System.Threading.Thread.Sleep(2000);  
  85.                     System.Environment.Exit(-1);  
  86.                 }  
  87.   
  88.                 //以下载入设定回调函数的函数,并调用  
  89.                 IntPtr hapi2 = GetProcAddress(hLib, "setRecvDataCallback");  
  90.                 if (hapi2 == IntPtr.Zero)  
  91.                 {  
  92.                     Console.WriteLine("load setRecvDataCallback failed! ErrorNuber:" + Marshal.GetLastWin32Error().ToString());  
  93.                 }  
  94.                 SetRecvDataCallback setRecvDataCallback =  
  95.                     (SetRecvDataCallback)Marshal.GetDelegateForFunctionPointer(hapi2, typeof(SetRecvDataCallback));  
  96.                 setRecvDataCallback(onMessage);  
  97.   
  98.                 IntPtr hapi3 = GetProcAddress(hLib, "sendMessage");  
  99.   
  100.   
  101.                 if (hapi3 == IntPtr.Zero)  
  102.                 {  
  103.                     Console.WriteLine("load sendMessage failed! ErrorNuber:" + Marshal.GetLastWin32Error().ToString());  
  104.                 }  
  105.                 sendMessage =  
  106.                    (SendMessage)Marshal.GetDelegateForFunctionPointer(hapi3, typeof(SendMessage));  
  107.                 Res = sendMessage(b);  
  108.                 if (Res != 0)  
  109.                 {  
  110.                     Console.WriteLine("sendMessage failed! \n");  
  111.                     System.Threading.Thread.Sleep(2000);  
  112.                     System.Environment.Exit(-1);  
  113.                 }  
  114.                 System.Threading.Thread.Sleep(1000);  
  115.             }  
  116.             else  
  117.             {  
  118.                 Res = sendMessage(b);  
  119.                 if (Res != 0)  
  120.                 {  
  121.                     Console.WriteLine("sendMessage failed! \n");  
  122.                     System.Threading.Thread.Sleep(2000);  
  123.                     System.Environment.Exit(-1);  
  124.                 }  
  125.                 System.Threading.Thread.Sleep(1000);  
  126.             }  
  127.   
  128.   
  129.   
  130.         }  
  131.       
  132.   
  133.          
  134.   
  135.   
  136.         public void Close()  
  137.         {  
  138.             int Res = -1;  
  139.             //以下载入关闭连接函数,并调用  
  140.             IntPtr hapi4 = GetProcAddress(hLib, "closePrinterManager");  
  141.             if (hapi4 == IntPtr.Zero)  
  142.             {  
  143.                 Console.WriteLine("load closePrinterManager failed! ErrorNuber:" + Marshal.GetLastWin32Error().ToString());  
  144.             }  
  145.             ClosePrinterManager closePrinterManager =  
  146.                 (ClosePrinterManager)Marshal.GetDelegateForFunctionPointer(hapi4, typeof(ClosePrinterManager));  
  147.             Res = closePrinterManager();  
  148.             if (Res != 0)  
  149.             {  
  150.                 Console.WriteLine("closePrinterManager failed! \n");  
  151.                 System.Threading.Thread.Sleep(2000);  
  152.                 System.Environment.Exit(-1);  
  153.             }  
  154.             //释放动态链接库  
  155.             FreeLibrary(hLib);  
  156.             Console.Read();  
  157.         }  
  158.     }  
  159. }  




查找原因发现回调函数需要声明一个静态对象来存储,改成以下之后,可以正常调用

[csharp]  view plain  copy
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4. using System.Runtime.InteropServices;  
  5.   
  6. namespace CSharpDemo  
  7. {  
  8.     class CSharpDemo  
  9.     {  
  10.         [UnmanagedFunctionPointer(CallingConvention.StdCall)]  
  11.         public delegate void WriteToConsoleCallback(IntPtr str);  
  12.   
  13.         [DllImport("kernel32.dll", EntryPoint = "LoadLibrary", SetLastError = true)]  
  14.         public static extern IntPtr LoadLibrary(  
  15.            [MarshalAs(UnmanagedType.LPStr)] string lpLibFileName);  
  16.   
  17.         [DllImport("kernel32.dll", EntryPoint = "GetProcAddress", SetLastError = true)]  
  18.         public static extern IntPtr GetProcAddress(IntPtr hModule,  
  19.                    [MarshalAs(UnmanagedType.LPStr)] string lpProcName);  
  20.   
  21.         [DllImport("kernel32.dll", EntryPoint = "FreeLibrary")]  
  22.         public static extern bool FreeLibrary(IntPtr hModule);  
  23.   
  24.         public delegate int InitPrinterManager();  
  25.         //public delegate void _onMessage_func(IntPtr str);  
  26.         //public delegate void SetRecvDataCallback(_onMessage_func callback);  
  27.         public delegate void SetRecvDataCallback(WriteToConsoleCallback callback);  
  28.         public delegate int SendMessage(byte[] str);  
  29.         public delegate int ClosePrinterManager();  
  30.         private static WriteToConsoleCallback callback;  
  31.   
  32.         public static string strMessage = "";  
  33.         public static IntPtr hLib;  
  34.         public static SendMessage sendMessage;  
  35.         //回调函数  
  36.         static void onMessage(IntPtr str)  
  37.         {  
  38.   
  39.             byte[] buffer1 = Encoding.Default.GetBytes(Marshal.PtrToStringAnsi(str));  
  40.             byte[] buffer2 = Encoding.Convert(Encoding.UTF8, Encoding.Default, buffer1, 0, buffer1.Length);  
  41.             string strBuffer = Encoding.Default.GetString(buffer2, 0, buffer2.Length);  
  42.   
  43.         }  
  44.         /// <summary>  
  45.         /// 连接  
  46.         /// </summary>  
  47.         public static void Websocket()  
  48.         {  
  49.             try  
  50.             {  
  51.                 //以下载入发送数据函数,并发送数据  
  52.                 string str = "{\"cmd\":\"print\",\"requestID\":\"123458976\",\"version\":\"1.0\"}";  
  53.                 byte[] b = System.Text.Encoding.UTF8.GetBytes(str);  
  54.   
  55.   
  56.                 //用于接口返回  
  57.                 int Res = -1;  
  58.                 //IntPtr hLib;  
  59.                 //以下动态载入dll库  
  60.                 if (hLib == IntPtr.Zero)  
  61.                 {  
  62.                     if (IntPtr.Size == 8)  
  63.                         hLib = LoadLibrary("PrinterManager64.dll");  
  64.                     else  
  65.                         hLib = LoadLibrary("PrinterManager32.dll");  
  66.   
  67.   
  68.                     if (hLib == IntPtr.Zero)  
  69.                     {  
  70.   
  71.                         Console.WriteLine("loadlibrary failed! ErrorNuber:" + Marshal.GetLastWin32Error().ToString());  
  72.                         System.Threading.Thread.Sleep(2000);  
  73.                         System.Environment.Exit(-1);  
  74.                     }  
  75.                     //以下载入初始化函数initPrinterManager  
  76.                     IntPtr hapi = GetProcAddress(hLib, "initPrinterManager");  
  77.                     if (hapi == IntPtr.Zero)  
  78.                     {  
  79.                         Console.WriteLine("load initPrinterManager failed! ErrorNuber:" + Marshal.GetLastWin32Error().ToString());  
  80.                         System.Threading.Thread.Sleep(2000);  
  81.                         System.Environment.Exit(-1);  
  82.                     }  
  83.                     //将初始化函数指针封装成委托,并调用  
  84.                     InitPrinterManager initPrinterManager =  
  85.                         (InitPrinterManager)Marshal.GetDelegateForFunctionPointer(hapi, typeof(InitPrinterManager));  
  86.                     Res = initPrinterManager();  
  87.                     if (Res != 0)  
  88.                     {  
  89.                         Console.WriteLine("run initPrinterManager failed! \n");  
  90.                         System.Threading.Thread.Sleep(2000);  
  91.                         System.Environment.Exit(-1);  
  92.                     }  
  93.   
  94.                     //以下载入设定回调函数的函数,并调用  
  95.                     IntPtr hapi2 = GetProcAddress(hLib, "setRecvDataCallback");  
  96.                     if (hapi2 == IntPtr.Zero)  
  97.                     {  
  98.                         Console.WriteLine("load setRecvDataCallback failed! ErrorNuber:" + Marshal.GetLastWin32Error().ToString());  
  99.                     }  
  100.                     SetRecvDataCallback setRecvDataCallback =  
  101.                         (SetRecvDataCallback)Marshal.GetDelegateForFunctionPointer(hapi2, typeof(SetRecvDataCallback));  
  102.                     //setRecvDataCallback(onMessage);  
  103.                     //setRecvDataCallback(null);  
  104.                     callback = new WriteToConsoleCallback(onMessage);  
  105.                     setRecvDataCallback(callback);  
  106.   
  107.                     IntPtr hapi3 = GetProcAddress(hLib, "sendMessage");  
  108.   
  109.   
  110.                     if (hapi3 == IntPtr.Zero)  
  111.                     {  
  112.                         Console.WriteLine("load sendMessage failed! ErrorNuber:" + Marshal.GetLastWin32Error().ToString());  
  113.                     }  
  114.                     sendMessage =  
  115.                        (SendMessage)Marshal.GetDelegateForFunctionPointer(hapi3, typeof(SendMessage));  
  116.                     Res = sendMessage(b);  
  117.                     if (Res != 0)  
  118.                     {  
  119.                         Console.WriteLine("sendMessage failed! \n");  
  120.                         System.Threading.Thread.Sleep(2000);  
  121.                         System.Environment.Exit(-1);  
  122.                     }  
  123.   
  124.                     System.Threading.Thread.Sleep(1000);  
  125.                 }  
  126.                 else  
  127.                 {  
  128.   
  129.                     Res = sendMessage(b);  
  130.                     if (Res != 0)  
  131.                     {  
  132.                         Console.WriteLine("sendMessage failed! \n");  
  133.                         System.Threading.Thread.Sleep(2000);  
  134.                         System.Environment.Exit(-1);  
  135.                     }  
  136.                     System.Threading.Thread.Sleep(1000);  
  137.                 }  
  138.             }  
  139.             catch (Exception ex)  
  140.             {  
  141.   
  142.             }  
  143.         }  
  144.         /// <summary>  
  145.         /// 关闭关闭连接函数  
  146.         /// </summary>  
  147.         public void Close()  
  148.         {  
  149.             int Res = -1;  
  150.             //以下载入关闭连接函数,并调用  
  151.             IntPtr hapi4 = GetProcAddress(hLib, "closePrinterManager");  
  152.             if (hapi4 == IntPtr.Zero)  
  153.             {  
  154.                 Console.WriteLine("load closePrinterManager failed! ErrorNuber:" + Marshal.GetLastWin32Error().ToString());  
  155.             }  
  156.             ClosePrinterManager closePrinterManager =  
  157.                 (ClosePrinterManager)Marshal.GetDelegateForFunctionPointer(hapi4, typeof(ClosePrinterManager));  
  158.             Res = closePrinterManager();  
  159.             if (Res != 0)  
  160.             {  
  161.                 Console.WriteLine("closePrinterManager failed! \n");  
  162.                 System.Threading.Thread.Sleep(2000);  
  163.                 System.Environment.Exit(-1);  
  164.             }  
  165.             //释放动态链接库  
  166.             FreeLibrary(hLib);  
  167.         }  
  168.       
  169.     }  
  170. }  

这篇关于c#调用C++ dll 报未将对象引用到设置对象的实例 的解决方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1040945

相关文章

Python设置Cookie永不超时的详细指南

《Python设置Cookie永不超时的详细指南》Cookie是一种存储在用户浏览器中的小型数据片段,用于记录用户的登录状态、偏好设置等信息,下面小编就来和大家详细讲讲Python如何设置Cookie... 目录一、Cookie的作用与重要性二、Cookie过期的原因三、实现Cookie永不超时的方法(一)

C# 比较两个list 之间元素差异的常用方法

《C#比较两个list之间元素差异的常用方法》:本文主要介绍C#比较两个list之间元素差异,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. 使用Except方法2. 使用Except的逆操作3. 使用LINQ的Join,GroupJoin

Python实现对阿里云OSS对象存储的操作详解

《Python实现对阿里云OSS对象存储的操作详解》这篇文章主要为大家详细介绍了Python实现对阿里云OSS对象存储的操作相关知识,包括连接,上传,下载,列举等功能,感兴趣的小伙伴可以了解下... 目录一、直接使用代码二、详细使用1. 环境准备2. 初始化配置3. bucket配置创建4. 文件上传到os

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的

Java中调用数据库存储过程的示例代码

《Java中调用数据库存储过程的示例代码》本文介绍Java通过JDBC调用数据库存储过程的方法,涵盖参数类型、执行步骤及数据库差异,需注意异常处理与资源管理,以优化性能并实现复杂业务逻辑,感兴趣的朋友... 目录一、存储过程概述二、Java调用存储过程的基本javascript步骤三、Java调用存储过程示

Visual Studio 2022 编译C++20代码的图文步骤

《VisualStudio2022编译C++20代码的图文步骤》在VisualStudio中启用C++20import功能,需设置语言标准为ISOC++20,开启扫描源查找模块依赖及实验性标... 默认创建Visual Studio桌面控制台项目代码包含C++20的import方法。右键项目的属性:

c++中的set容器介绍及操作大全

《c++中的set容器介绍及操作大全》:本文主要介绍c++中的set容器介绍及操作大全,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录​​一、核心特性​​️ ​​二、基本操作​​​​1. 初始化与赋值​​​​2. 增删查操作​​​​3. 遍历方

java向微信服务号发送消息的完整步骤实例

《java向微信服务号发送消息的完整步骤实例》:本文主要介绍java向微信服务号发送消息的相关资料,包括申请测试号获取appID/appsecret、关注公众号获取openID、配置消息模板及代码... 目录步骤1. 申请测试系统2. 公众号账号信息3. 关注测试号二维码4. 消息模板接口5. Java测试