C# 调用非托管C++ DLL 问题

问题描述

直接上代码:C++头文件中:CTestDLLextern"C"_declspec(dllexport)bool__stdcallFunc1(double*data,introws,intcolumns);CTestDLLextern"C"_declspec(dllexport)bool__stdcallFunc2(double*WL,double*SV,double*Result,PointInfopointinfo);CTestDLLextern"C"_declspec(dllexport)int__stdcallFunc3();C++cpp文件中boolFunc2(double*WL,double*SV,double*Result,PointInfopointinfo){index++;returncalpoint.Run(WL,SV,Result,pointinfo);}boolFunc1(double*data,introws,intcolumns){index++;//returntrue;returncalpoint.Set(data,rows,columns);}intFunc3(){index++;returnindex;}C#publicclassSpec{[DllImport("CTestDLL.dll",EntryPoint="Func2",ExactSpelling=false,CallingConvention=CallingConvention.Cdecl)]publicstaticexternboolFunc2(IntPtrWL,IntPtrSV,IntPtrResult,PointInfopointinfo);[DllImport("CTestDLL.dll",EntryPoint="Func1",ExactSpelling=false,CallingConvention=CallingConvention.Cdecl)]publicstaticexternboolFunc1(IntPtrdata,introws,intcolumns);[DllImport("CTestDLL.dll",EntryPoint="Func3",ExactSpelling=false,CallingConvention=CallingConvention.Cdecl)]publicstaticexternintFunc3();publicstructPointInfo{[MarshalAs(UnmanagedType.I4)]publicintP1;[MarshalAs(UnmanagedType.I4)]publicintP2;[MarshalAs(UnmanagedType.R8)]publicdoubleP3;[MarshalAs(UnmanagedType.R8)]publicdoubleP4;[MarshalAs(UnmanagedType.R8)]publicdoubleP5;[MarshalAs(UnmanagedType.R8)]publicdoubleP6;[MarshalAs(UnmanagedType.I4)]publicintP7;[MarshalAs(UnmanagedType.R8)]publicdoubleP8;};}使用时发现inta=Spec.Func3();(调用正常,能调试进入C++)double[]specData=newdouble[1000];GCHandleunmanageddata=GCHandle.Alloc(specData,GCHandleType.Pinned);boolisok=Spec.Func1(unmanageddata.AddrOfPinnedObject(),100,10);(有返回值,但调试无法进入C++)之前在调试Func1,和Func2时一切正常,能够调试跟踪进入C++代码,但是昨天下午我修改了部分C++代码后,就无法调试进入C++了,然后今天添加了一个Func3发现Func3能正常调试,Func1,Func2仍然无法调试进入。

解决方案

解决方案二:
1、确保函数都调用到了2、确保符号文件是正确的3、在c++的函数里放个断点
解决方案三:
C++代码里写的是__stdcall,为什么C#里用的是Cdecl
解决方案四:
引用1楼shingoscar的回复:

1、确保函数都调用到了2、确保符号文件是正确的3、在c++的函数里放个断点

1、确保函数都调用到是什么意思?是指C++里面有函数调用问题还是C#调用不对?C++、C#都正常编译没有报错,C#运行到Func1、Func2直接跳过,没有抛出任何异常,获取的结果不对,但通过Func3得到的index的值表明Func1、Func2里面index++执行正确;2、符号文件指的是.pdb文件?我都是一起copy的应该不会错;3、C++里面三个函数都放了断点的,没有用。
解决方案五:
引用2楼iyomumx的回复:

C++代码里写的是__stdcall,为什么C#里用的是Cdecl

我把C#中改为stdcall后,调用Func3正常,调用Func1、Func2时提示:ManagedDebuggingAssistant‘PInvokeStackImbalance’hasdetecedaproblemin“xxxxxxxx”。AdditionalInformation:AcalltoPInvokefunction‘Spec::Func1’hasunbalancedthestack.ThislikelybecausethemanagedPInvokesignaturedoesnotmatchtheunmanagedtargetsignature.CheckthecallingconventionandparametersofthePInvokesignaturematchthetargetunmanagedsignature.
解决方案六:
引用4楼yjh18v的回复:

Quote: 引用2楼iyomumx的回复:
C++代码里写的是__stdcall,为什么C#里用的是Cdecl

我把C#中改为stdcall后,调用Func3正常,调用Func1、Func2时提示:ManagedDebuggingAssistant‘PInvokeStackImbalance’hasdetecedaproblemin“xxxxxxxx”。AdditionalInformation:AcalltoPInvokefunction‘Spec::Func1’hasunbalancedthestack.ThislikelybecausethemanagedPInvokesignaturedoesnotmatchtheunmanagedtargetsignature.CheckthecallingconventionandparametersofthePInvokesignaturematchthetargetunmanagedsignature.

cpp文件里也要__stdcall

时间: 2024-09-13 21:06:31

C# 调用非托管C++ DLL 问题的相关文章

.net 服务多线程 调用非托管C++DLL 如何防止 服务崩溃?

问题描述 .net 服务多线程 调用非托管C++DLL 如何防止 服务崩溃? 有一个.net服务,服务中开了多线程.其中有一线程会去调用非托管C++DLL,并阻塞等待其返回值.其他线程同步做文件处理.数据状态更新等操作.现在调用非托管C++DLL的线程会因为非托管代码的问题,崩溃.这样整个服务也就崩溃了!需要人工去服务器上重启该服务!请问:如何防止整个服务崩溃?是否可以捕获非托管C++中的错误.因为已经try catch了,但什么都捕获不到,直接服务崩溃! 解决方案 这个应该要想办法解决C++

C#调用非托管C++DLL中的函数接口

问题描述 C#调用非托管C++DLL中的函数接口(有生成的DLL文件和Lib文件)怎么引用?引用项添加不了 解决方案 解决方案二:使用DllImport,添加引用只能针对.NET控件或COM组件.解决方案三:DllImport具体搜p/Invokehttp://www.cnblogs.com/xuqiang/archive/2010/12/21/1953355.html解决方案四:C++DLL中的函数中还调用了openCV的函数,能说一下怎么整么?解决方案五:引用3楼qq_28744297的回复

调用非托管dll常出现的bug及解决办法

C和C++有很多好的类库的沉淀,在.NET中,完全抛弃它们而重头再来是非常不明智的.也是不现实的,所以,我们经常需要通过Pinvoke来使用以前遗留下来的非托管的dll.就.NET中使用非托管的dll经验而言,经常碰到的问题至少有两个,它们都是通过在运行时抛出异常来体现的. 1.试图加载格式不正确的程序 出现这种异常,通常是.NET应用程序的"目标平台"与非托管dll的平台不一样. 一般,在使用VS开发.NET的应用程序和类库时,默认的目标平台为"Any CPU",

非托管dll-C#调用非托管DLL,报“其他内存已损坏”,请问怎么解决呢?

问题描述 C#调用非托管DLL,报"其他内存已损坏",请问怎么解决呢? 定义: [DllImport("BSEncrypt.dll")] public static extern bool MD5String(ref string instr, int inlen, ref string outstr, int outlen); 调用: String ls_MD5Password = new String('', 100); string as_Password =

关于c#动态调用非托管DLL的内存释放问题

问题描述 本人由于客户的需要,需要在程序的运行过程中,动态加载不同的DLL.这与直接调用非托管DLL不一样.下面这个帖子中的第三个方法很好的说明了如何动态调用非托管DLL.http://blog.csdn.net/pansiom/article/details/568096#comments为了方便使用,我把文中的方法弄成了一个DLDApi类,如下usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Re

在VS2010上使用C#调用非托管C++生成的DLL文件(图文讲解) 背景

背景       在项目过程中,有时候你需要调用非C#编写的DLL文件,尤其在使用一些第三方通讯组件的时候,通过C#来开发应用软件时,就需要利用DllImport特性进行方法调用.本篇文章将引导你快速理解这个调用的过程.   步骤 1. 创建一个CSharpInvokeCPP的解决方案:   2. 创建一个C++的动态库项目:   3. 在应用程序设置中,选择"DLL",其他按照默认选项: 最后点击完成,得到如图所示项目:       我们可以看到这里有一些文件,其中dllmain.c

.net- C#与非托管C++DLL交互问题

问题描述 C#与非托管C++DLL交互问题 我封装了一个C++dll,是用C++调用SQLite的数据库,再返回查询出的数据内容. 现在的问题是, 我用C#调用C++的dll的时候,不知道参数该如何传递. C++取得的数据库内容结果是char***的三维数组,我该如何传给C#层呢? C#取到数据后,又该如何转换成DataTable呢_? 请各位大神指教,最好能有简单的代码例子, 在此先谢过了. 解决方案 直接用byte[]去取就可以了,然后循环拆分. 解决方案二: 循环去取的话,不是每个字段就要

.net 调用 非托管C++的类

问题描述 背景:安装了一个开发包,通过开发包中的SaperaBasic类(很多类的统称)可以用C++或.net开发控制它们公司硬件的软件,SaperaBasic类包含两种类库:.net调用的和C++调用的(非托管),我需要使用.net开发(CLR,即C++.net),我选择的硬件是由一个叫SaperaRTPro类控制的,它是继承自SaperaBasic中的一两个类生成的,问题来了:因为我选的硬件不具有代表性,所以这个公司只提供了SaperaRTPro的C++类库(.h文件和DLL文件),我怎么在

C#调用非托管的代码

using System; using System.Runtime.InteropServices; namespace 调用非托管项目demo { class Program { static void Main(string[] args) { Win32.MessageBox(0, "Hello I am Kun", "stm32", 0); } public class Win32 { [DllImport("user32.dll",