C# 带有C++ DLL的C迭代服务在Excel中工作? 我有一个C++ DLL,我想在我的C项目中工作,我对C++和C一无所知,但是有源码,可以在VS201/P>中打开和构建它
dll附带了Excel VBA中的工作示例,但我无法让它在C中工作 我一直遇到的错误是 附加信息:调用PInvoke函数 “真的!RMTest.PInvokeTest::encode_eib_d'使堆栈不平衡。 这可能是因为托管PInvoke签名不匹配 不受管理的 我的C测试代码如下C# 带有C++ DLL的C迭代服务在Excel中工作? 我有一个C++ DLL,我想在我的C项目中工作,我对C++和C一无所知,但是有源码,可以在VS201/P>中打开和构建它,c#,c++,pinvoke,dllimport,interopservices,C#,C++,Pinvoke,Dllimport,Interopservices,dll附带了Excel VBA中的工作示例,但我无法让它在C中工作 我一直遇到的错误是 附加信息:调用PInvoke函数 “真的!RMTest.PInvokeTest::encode_eib_d'使堆栈不平衡。 这可能是因为托管PInvoke签名不匹配 不受管理的 我的C测试代码如下 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threadin
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
namespace RMTest
{
class Program
{
static void Main(string[] args)
{
string s1 = "2";
string s2 = "1";
string s3 = "1";
string s4 = "1";
string s5 = "TESTTE";
var res = PInvokeTest.encode_eib_d(s1, s2, s3, s4, s5);
}
}
class PInvokeTest
{
[DllImport("UKRM_EncodeEIB_D.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
public static extern string encode_eib_d(string infoID, string versionID, string format, string sClass, string licNum);
}
}
Public Declare _
Function encode_eib_d Lib "UKRM_EncodeEIB_D.dll" (ByVal inInfoID As String, ByVal inVersionID As String, ByVal inClass As String, _
ByVal inFormat As String, ByVal inLicenseNum As String) As Variant
Function ENCODE_D(inInfoID As String, inVersionID As String, inFormat As String, inClass As String, inLicenseNum As String) As Variant
Dim error As Integer
ChDrive (ActivePath())
ChDir (ActivePath())
On Error GoTo ErrHandler:
ENCODE_D = encode_eib_d(inInfoID, inVersionID, inFormat, inClass, inLicenseNum)
ErrHandler:
If Err.Number <> 0 Then
ENCODE_D = Err.Description
End If
End Function
作为参考,Excel中的工作示例,VBA如下所示
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
namespace RMTest
{
class Program
{
static void Main(string[] args)
{
string s1 = "2";
string s2 = "1";
string s3 = "1";
string s4 = "1";
string s5 = "TESTTE";
var res = PInvokeTest.encode_eib_d(s1, s2, s3, s4, s5);
}
}
class PInvokeTest
{
[DllImport("UKRM_EncodeEIB_D.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
public static extern string encode_eib_d(string infoID, string versionID, string format, string sClass, string licNum);
}
}
Public Declare _
Function encode_eib_d Lib "UKRM_EncodeEIB_D.dll" (ByVal inInfoID As String, ByVal inVersionID As String, ByVal inClass As String, _
ByVal inFormat As String, ByVal inLicenseNum As String) As Variant
Function ENCODE_D(inInfoID As String, inVersionID As String, inFormat As String, inClass As String, inLicenseNum As String) As Variant
Dim error As Integer
ChDrive (ActivePath())
ChDir (ActivePath())
On Error GoTo ErrHandler:
ENCODE_D = encode_eib_d(inInfoID, inVersionID, inFormat, inClass, inLicenseNum)
ErrHandler:
If Err.Number <> 0 Then
ENCODE_D = Err.Description
End If
End Function
.def:
我在输入参数上尝试了MarshalAs等的各种组合,也尝试了StringBuilders而不是字符串,但听起来好像它对从一个到另一个的方法签名不满意
令人沮丧的是,它在VBA中工作
如果您需要更多信息,请询问
谢谢。在您的情况下,您需要一个pinvoke签名,如:
[DllImport("UKRM_EncodeEIB_D.dll", CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.BStr)]
public static extern string encode_eib_d(
[MarshalAs(UnmanagedType.LPStr)]string infoID,
[MarshalAs(UnmanagedType.LPStr)]string versionID,
[MarshalAs(UnmanagedType.LPStr)]string format,
[MarshalAs(UnmanagedType.LPStr)]string sClass,
[MarshalAs(UnmanagedType.LPStr)]string licNum);
你的意思是要切换PInvoke调用的3/4参数的名称吗?VB调用也返回varient,但在C调用中返回字符串。C中最接近的匹配是object。这是因为返回类型。Variant是一个结构,由于某种原因,您可以任意转换为字符串。您需要将其更改为object并应用[return:MarshalAsUnmanagedType.Struct]属性。@Hans-我使用了Jcl发布的以下代码,但将返回类型更改为上述object和return属性。。。我现在得到的错误是附加信息:PInvoke限制:无法返回变量。不,LPCSTR是const char*Oops,没错,我想是LPCTSTR。将编辑
[DllImport("UKRM_EncodeEIB_D.dll", CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.BStr)]
public static extern string encode_eib_d(
[MarshalAs(UnmanagedType.LPStr)]string infoID,
[MarshalAs(UnmanagedType.LPStr)]string versionID,
[MarshalAs(UnmanagedType.LPStr)]string format,
[MarshalAs(UnmanagedType.LPStr)]string sClass,
[MarshalAs(UnmanagedType.LPStr)]string licNum);