C# 带有C++ DLL的C迭代服务在Excel中工作? 我有一个C++ DLL,我想在我的C项目中工作,我对C++和C一无所知,但是有源码,可以在VS201/P>中打开和构建它

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

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.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);