问题描述
直接上代码: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