【问题标题】:Call C# function from native C++ or C从本机 C++ 或 C 调用 C# 函数
【发布时间】:2012-06-20 13:30:40
【问题描述】:

我正在尝试按照以下步骤操作:Calling C# from C++, Reverse P/Invoke, Mixed Mode DLLs and C++/CLI 1.我制作了名为TestLib的C# Dll:

namespace TestLib
{
    public class TestClass
    {
        public float Add(float a, float b)
        {
            return a + b;
        }
    }
}

2。然后我创建名为 WrapperLib 的 C++/CLI Dll 并添加对 C# TestLib 的引用。

// WrapperLib.h

#pragma once

using namespace System;
using namespace TestLib;

namespace WrapperLib {

    public class WrapperClass
    {
    float Add(float a, float b)
        {
        TestClass^ pInstance = gcnew TestClass();
        //pInstance
        // TODO: Add your methods for this class here.
        return pInstance->Add(a, b);
        }
    };
}

C+ 3. 对于检查 tis 示例,我创建了 C++/CLI 控制台应用程序并尝试调用此代码:

// ConsoleTest.cpp : main project file.

#include "stdafx.h"

using namespace System;
using namespace WrapperLib;

int main(array<System::String ^> ^args)
{
    Console::WriteLine(L"Hello World");
    WrapperClass cl1 = new WrapperClass();

    return 0;
}

但我得到了一些错误:

error C2065: 'WrapperClass' : undeclared identifier C:\Projects\TestSolution\ConsoleTest\ConsoleTest.cpp    11  1   ConsoleTest
error C2146: syntax error : missing ';' before identifier 'cl1' C:\Projects\TestSolution\ConsoleTest\ConsoleTest.cpp    11  1   ConsoleTest
error C2065: 'cl1' : undeclared identifier  C:\Projects\TestSolution\ConsoleTest\ConsoleTest.cpp    11  1   ConsoleTest
error C2061: syntax error : identifier 'WrapperClass'   C:\Projects\TestSolution\ConsoleTest\ConsoleTest.cpp    11  1   ConsoleTest

我知道我错过了什么地方,但是在哪里?

【问题讨论】:

  • 如果编译器告诉你“嘿,有一些错误,请修复”你会先看哪里? :) 请告诉我们错误是什么。
  • 已修复。我已经添加了 VS 输出。如何从原生 C++ 或 C 中正确调用此函数?

标签: c# c++-cli pinvoke


【解决方案1】:

根据@Ben Voigt 的建议,我认为您的代码应该看起来像这样:

// ConsoleTest.cpp : main project file.

#include "stdafx.h"
#include "WrapperLib.h"

using namespace System;
using namespace WrapperLib;

int main(array<System::String ^> ^args)
{
    float result;
    Console::WriteLine(L"Hello World");
    WrapperClass cl1;

    result = cl1.Add(1, 1);

    return 0;
}

如果您不包含包装库的头文件,C++ 编译器将永远找不到它的函数,并且您将不断收到之前显示的错误。

【讨论】:

  • 我的 WrapperLib 项目包含 WrapperLib.h 和代码,WrapperLib.cpp 只包含:#include "stdafx.h" #include "WrapperLib.h" 对吗?
  • 是的,我相信这是正确的,但是您需要将 WrapperLib 头文件#include 到您的主项目(您用来测试它的那个)中。正如@Mark Simith 上面所说,在本机 C++ 中,您是否引用了另一个项目并不重要,您仍然需要包含头文件。
【解决方案2】:

这不是好的 C++,看起来像 Java 或 C#。

在 C++/CLI 中创建新对象的正确语法是

WrapperClass cl1;

WrapperClass^ cl1 = gcnew WrapperClass();

C++ 有栈语义,你必须告诉编译器你想要一个在函数末尾自动释放的本地对象(第一个选项),还是一个可以活得更久的句柄(第二个选项,使用^gcnew)。

【讨论】:

  • 我尝试使用 WrapperClass^ cl1 = gcnew WrapperClass();但我收到错误:错误 1 ​​错误 C2065:“WrapperClass”:未声明的标识符错误 C2065:“cl1”:未声明的标识符错误 C2061:语法错误:标识符“WrapperClass”
  • @Superjet100:你还需要#include "WrapperLib.h"
  • 但是在这个测试控制台应用程序中我没有#include "WrapperLib.h"
  • @Superjet100:哦,这是一个单独的项目?然后添加对定义WrapperLib::WrapperClass的项目的引用。
  • 对于来自另一个 dll 的本地类(如 WrapperClass),要使它们在您的翻译单元中可见,您需要#include 其头文件(就像标准 C++ 代码一样)。对于来自另一个 dll 的托管类,您只需添加对项目的引用(就像在 C# 中一样)。
猜你喜欢
  • 2017-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多