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

相关文章

Java调用Python的四种方法小结

《Java调用Python的四种方法小结》在现代开发中,结合不同编程语言的优势往往能达到事半功倍的效果,本文将详细介绍四种在Java中调用Python的方法,并推荐一种最常用且实用的方法,希望对大家有... 目录一、在Java类中直接执行python语句二、在Java中直接调用Python脚本三、使用Run

Python如何调用指定路径的模块

《Python如何调用指定路径的模块》要在Python中调用指定路径的模块,可以使用sys.path.append,importlib.util.spec_from_file_location和exe... 目录一、sys.path.append() 方法1. 方法简介2. 使用示例3. 注意事项二、imp

MySQL主从同步延迟问题的全面解决方案

《MySQL主从同步延迟问题的全面解决方案》MySQL主从同步延迟是分布式数据库系统中的常见问题,会导致从库读取到过期数据,影响业务一致性,下面我将深入分析延迟原因并提供多层次的解决方案,需要的朋友可... 目录一、同步延迟原因深度分析1.1 主从复制原理回顾1.2 延迟产生的关键环节二、实时监控与诊断方案

在.NET平台使用C#为PDF添加各种类型的表单域的方法

《在.NET平台使用C#为PDF添加各种类型的表单域的方法》在日常办公系统开发中,涉及PDF处理相关的开发时,生成可填写的PDF表单是一种常见需求,与静态PDF不同,带有**表单域的文档支持用户直接在... 目录引言使用 PdfTextBoxField 添加文本输入域使用 PdfComboBoxField

Python开发文字版随机事件游戏的项目实例

《Python开发文字版随机事件游戏的项目实例》随机事件游戏是一种通过生成不可预测的事件来增强游戏体验的类型,在这篇博文中,我们将使用Python开发一款文字版随机事件游戏,通过这个项目,读者不仅能够... 目录项目概述2.1 游戏概念2.2 游戏特色2.3 目标玩家群体技术选择与环境准备3.1 开发环境3

CentOS和Ubuntu系统使用shell脚本创建用户和设置密码

《CentOS和Ubuntu系统使用shell脚本创建用户和设置密码》在Linux系统中,你可以使用useradd命令来创建新用户,使用echo和chpasswd命令来设置密码,本文写了一个shell... 在linux系统中,你可以使用useradd命令来创建新用户,使用echo和chpasswd命令来设

电脑找不到mfc90u.dll文件怎么办? 系统报错mfc90u.dll丢失修复的5种方案

《电脑找不到mfc90u.dll文件怎么办?系统报错mfc90u.dll丢失修复的5种方案》在我们日常使用电脑的过程中,可能会遇到一些软件或系统错误,其中之一就是mfc90u.dll丢失,那么,mf... 在大部分情况下出现我们运行或安装软件,游戏出现提示丢失某些DLL文件或OCX文件的原因可能是原始安装包

电脑显示mfc100u.dll丢失怎么办?系统报错mfc90u.dll丢失5种修复方案

《电脑显示mfc100u.dll丢失怎么办?系统报错mfc90u.dll丢失5种修复方案》最近有不少兄弟反映,电脑突然弹出“mfc100u.dll已加载,但找不到入口点”的错误提示,导致一些程序无法正... 在计算机使用过程中,我们经常会遇到一些错误提示,其中最常见的就是“找不到指定的模块”或“缺少某个DL

C#如何调用C++库

《C#如何调用C++库》:本文主要介绍C#如何调用C++库方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录方法一:使用P/Invoke1. 导出C++函数2. 定义P/Invoke签名3. 调用C++函数方法二:使用C++/CLI作为桥接1. 创建C++/CL

C#使用StackExchange.Redis实现分布式锁的两种方式介绍

《C#使用StackExchange.Redis实现分布式锁的两种方式介绍》分布式锁在集群的架构中发挥着重要的作用,:本文主要介绍C#使用StackExchange.Redis实现分布式锁的... 目录自定义分布式锁获取锁释放锁自动续期StackExchange.Redis分布式锁获取锁释放锁自动续期分布式