正确地将C ++ long转换为C#int

时间:2019-01-07 09:02:09

标签: c# c++ .net

我目前正在使用以非托管C ++编写的业务逻辑库来开发.NET Framework 4.7.2应用程序。 我需要使用不受管理的C ++

我需要使用C ++项目中的逻辑,不幸的是,我无法正确转换程序的输入或输出参数。

当我输入42并仅想返回该值时,结果为17582022。实际上应该是42。

我的C ++代码如下:

MYCore头文件:

<SafeAreaView style={{flex: 1}}>
   [...Your view component]
</SafeAreaView>

MYCore源文件:

#ifdef MYCORE_EXPORTS
#define MYCORE_API __declspec(dllexport)
#endif

#pragma once
#include <string>

using namespace std;

extern "C"
{
    class MYCORE_API TestClass
    {
    private:
        string name;
    public:
        TestClass(char*);
        long Iterate(long &n);
    };

    MYCORE_API TestClass* TestClass_Create(char* name);
}

我正在使用.NET 4.7.2 Framework Interface项目导出C ++库功能:

#include "stdafx.h"

#include "MYCore.h"

TestClass::TestClass(char* n) 
{
    name = n;
}

long TestClass::Iterate(long &n) 
{
    return n;
}

extern "C"
{
    MYCORE_API TestClass * TestClass_Create(char* name)
    {
        return new TestClass(name);
    }
}

在我的实际应用程序中,我进一步导入dll并使用如下逻辑:

namespace MYCore.Interface
{
    public static class MYProxy
    {
        private const string coreDLL = "my.core.dll";

        [DllImport(coreDLL, CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr TestClass_Create(string name);

        [DllImport(coreDLL, EntryPoint = "?Iterate@TestClass@@XXXXX@X", CallingConvention = CallingConvention.ThisCall)]
        public static extern int Iterate(int n);
    }
}

您知道如何正确将int输入从C#转换为C ++,反之亦然吗?

谢谢!

2 个答案:

答案 0 :(得分:3)

您在C#中所做的操作在C ++中也不起作用:

auto result = Iterate(42l);

导致编译器错误

  

无法将参数1从'long'转换为'long&'

我看到两种解决方案:

a)更改C ++代码

long TestClass::Iterate(long n)

(无参考文献)

b)更改C#代码

static extern int Iterate(ref int n);

(传递参考)并像这样调用它

int n = 42;
Console.WriteLine(Iterate(ref n));

答案 1 :(得分:1)

该问题实际上称为“将非托管C ++类编组为C#”。

在代理类中,我创建了一个方法来调用实际的实例方法:

[DllImport(coreDLL, EntryPoint = "?Iterate@TestClass@@XXX@X", CallingConvention = CallingConvention.ThisCall)]
public static extern int CallIterate(IntPtr instance, int n);

和我的C ++中的方法如下:

MYCORE_API int CallIterate(TestClass * instance, int n)
{
    if (instance!= NULL) 
    {
        return instance->Iterate(n);
    }
}

有关如何封送非托管C ++类的更多信息,我可以建议以下文章:

https://www.codeproject.com/Articles/18032/How-to-Marshal-a-C-Class

我的解决方案现在可以正常工作了。感谢您的所有宝贵意见!