尝试从 C++/CLI 调用非托管 C++ 时解决错误

Posted

技术标签:

【中文标题】尝试从 C++/CLI 调用非托管 C++ 时解决错误【英文标题】:Solving errors when trying to call unmanaged C++ from C++/CLI 【发布时间】:2012-02-21 15:54:45 【问题描述】:

我有一些想在 C# 中使用的本机 C++ 代码,经过一些研究后,我决定为本机代码创建一个 C++/CLI 包装器。到现在为止还挺好。运行包含 C++/CLI 类的程序时,它运行良好,但是当我尝试创建库以提供在 C# 中使用本机代码功能的机会时,我收到上述错误(LNK2028 和 LNK2019 )。尽管我已经为链接器和编译器尝试了几种配置,但我仍然无法摆脱这些错误。

这是工作包装器的代码:

//Wrapper_src.h

#include <cstdio>
#include "Project_Manager.h"

using namespace System;

public ref class WrapperParabola

private:
    ProjectManager *mainPM; //ProjectManager is the main class from the native code

public:
    WrapperParabola()
    
        mainPM = new ProjectManager;
    

    void InitSphereInfo(float R, float Cx, float Cy, float Cz, float H0, float H1, float dH, int segm)
    
        mainPM->Init_SphereInfo(R, Cx, Cy, Cz, H0, H1, dH, segm);
    

    void InitParableInfo(float P, float Refl, int Lsegm, int HSegm, float Lng)
    
        mainPM->Init_ParableInfo(P, Refl, Lsegm, HSegm, Lng);
    

    void InitRaysSetUpInfo(float Ora0, float Ora1, float dOra, int GridN, int NRays)
    
        mainPM->Init_RaysSetUpInfo(Ora0, Ora1, dOra, GridN, NRays);
    

    void InitSTPInfo(int zi, int luna, float LongLegala, float LongLoc, float Latitudine, float OraLegala, float UnghiInclinare, float UnghiAbatere)
    
        mainPM->Init_STPInfo(zi, luna, LongLegala, LongLoc, Latitudine, OraLegala, UnghiInclinare, UnghiAbatere);
    

    void ProcessData(void)
    
        mainPM->ProcessData();
    

    void PrintOutputData(void)
    
        mainPM->PrintOutputData();
    

    ~WrapperParabola()
    
        this->!WrapperParabola();
    

    !WrapperParabola()
    
        delete mainPM;
    
;


int main(void)

/*********************Test**********************/
WrapperParabola^ wrapperP = gcnew WrapperParabola;

//Init input data
wrapperP->InitSphereInfo(0, 0, 0, 0, 0, 0, 0, 0);
wrapperP->InitParableInfo(0, 0, 0, 0, 0);
wrapperP->InitRaysSetUpInfo(0, 0, 0, 0, 0);
wrapperP->InitSTPInfo(0, 0, 0, 0, 0, 0, 0, 0);

//Process read data
wrapperP->ProcessData();

//Print the results
wrapperP->PrintOutputData();

Console::WriteLine("Data Processed Successfully!");
std::getchar();     

return 0;

这是我正在尝试构建的库的代码:

// CppCodeManagerLib.h
#pragma once

#include "Project_Manager.h"

using namespace System;

namespace CppCodeManagerLib 

public ref class CodeManager

private:
    ProjectManager *mainPM;
public:
    CodeManager()                     
    
        mainPM = new ProjectManager;
    

    void InitSphereInfo(float R, float Cx, float Cy, float Cz, float H0, float H1, float dH, int segm)
    
        mainPM->Init_SphereInfo(R, Cx, Cy, Cz, H0, H1, dH, segm);
    

    /*...*/
;

正如我所说,我对必须对代码(本地代码或托管代码)或提供给链接器和编译器的命令和限制进行的更改感兴趣,以便使代码在 C# 中可用。

P.S:完整的错误是:

Error   2   error LNK2028:unresolved token (0A00003A) "public: void __thiscall ProjectManager::Init_SphereInfo(float,float,float,float,float,float,float,int)" 
(?Init_SphereInfo@ProjectManager@@$$FQAEXMMMMMMMH@Z) referenced in function "public: void __clrcall CppCodeManagerLib::CodeManager::InitSphereInfo(float,float,float,float,float,float,float,int)" 
(?InitSphereInfo@CodeManager@CppCodeManagerLib@@$$FQ$AAMXMMMMMMMH@Z) E:\Documents and Settings\zalman\Desktop\CppCodeManagerLib\CppCodeManagerLib\CppCodeManagerLib.obj CppCodeManagerLib

Error   3   error LNK2019: unresolved external symbol "public: void __thiscall ProjectManager::Init_SphereInfo(float,float,float,float,float,float,float,int)" 
(?Init_SphereInfo@ProjectManager@@$$FQAEXMMMMMMMH@Z) referenced in function "public: void __clrcall CppCodeManagerLib::CodeManager::InitSphereInfo(float,float,float,float,float,float,float,int)"
(?InitSphereInfo@CodeManager@CppCodeManagerLib@@$$FQ$AAMXMMMMMMMH@Z)    E:\Documents and Settings\zalman\Desktop\CppCodeManagerLib\CppCodeManagerLib\CppCodeManagerLib.obj  CppCodeManagerLib

谢谢!

【问题讨论】:

发布您的实际错误消息,而不仅仅是错误编号。另外,您使用的是/clr 还是/clr:pure @ildjarn。我ve poested the compelte error messages. Also, Im 使用/clr 我假设您已将包含 ProjectManager 实现的库添加到链接器输入中? 【参考方案1】:

根据 LNK2028 的 MSDN 页面,这是由于指定(或默认)的调用约定不匹配。 http://msdn.microsoft.com/en-us/library/ms235590%28v=vs.80%29.aspx

【讨论】:

以上是关于尝试从 C++/CLI 调用非托管 C++ 时解决错误的主要内容,如果未能解决你的问题,请参考以下文章

非托管C++通过C++/CLI包装调用C# DLL

C# 使用 CLI 包装器调用非托管 C++

通过 CLI 包装器在非托管 C++ 中使用 C#.NET Winform - 需要线程?

使用 C++/CLI 包装器将二维数组从 C# 传递到非托管 C++

用 C++/CLI 包装非托管 C++ - 一种正确的方法

如何为非托管 c dll 创建 c++\cli 包装器