繁体   English   中英

Mono MSC C# 编译器如何添加程序集引用

[英]Mono MSC C# compiler how to add assembly references

所以我试图在 mono 中运行 .NET C# 脚本,但我收到缺少程序集的错误...

C:\Users\user\Documents\GitHub\callCsharp-fromCPP\CMonoTest\Mp3ToSpeech.cs(1,14): error CS0234: The type or namespace name `Speech' does not exist in the namespace `System'. Are you missing an assembly reference?
C:\Users\user\Documents\GitHub\callCsharp-fromCPP\CMonoTest\Mp3ToSpeech.cs(6,7): error CS0246: The type or namespace name `NAudio' could not be found. Are you missing an assembly reference?
C:\Users\user\Documents\GitHub\callCsharp-fromCPP\CMonoTest\SeleniumWebdriver.cs(1,7): error CS0246: The type or namespace name `OpenQA' could not be found. Are you missing an assembly reference?
...

这是我当前的 C++ 代码

#include <windows.h>
#include <mono/jit/jit.h>
#include <mono/metadata/assembly.h>
#include <mono/metadata/debug-helpers.h>
#include <cstdlib>
#include <string>
#include <iostream>
#include <sstream>
#include <direct.h>
#include <filesystem>


#pragma comment(lib, "mono-2.0-boehm.lib") // replaced from mono-2.0.lib
#pragma comment(lib, "mono-2.0-sgen.lib") // It is new with GC code library GC from Gnu Compilication
#pragma comment(lib , "MonoPosixHelper.lib")

std::string get_working_path()
{
    char temp[260]; // max windows path length
    return (_getcwd(temp, sizeof(temp)) ? std::string(temp) : std::string(""));
}

int main(int argc, char* argv[])
{
#pragma region Load and compile the script
    std::string Mp3Path = std::filesystem::path(get_working_path()).parent_path().string() + R"(\CMonoTest\ChromeDriverInstaller.cs  )";
    std::string ProgramPath = std::filesystem::path(get_working_path()).parent_path().string() + R"(\CMonoTest\Program.cs  )";
    std::string ChromeInstPath = std::filesystem::path(get_working_path()).parent_path().string() + R"(\CMonoTest\Mp3ToSpeech.cs  )";
    std::string SeleniumWebPath = std::filesystem::path(get_working_path()).parent_path().string() + R"(\CMonoTest\SeleniumWebdriver.cs  )";
    //C:\Users\user\.nuget\packages\dotnetseleniumextras.waithelpers\3.11.0\lib\net45\SeleniumExtras.WaitHelpers.dll
    //C:\Users\user\.nuget\packages\naudio\2.1.0\lib\net6.0\NAudio.dll
    //C:\Users\user\.nuget\packages\selenium.support\4.4.0\lib\net5.0\WebDriver.Support.dll
    //C:\Users\user\.nuget\packages\selenium.webdriver\4.4.0\lib\net5.0\WebDriver.dll
    //C:\Users\user\.nuget\packages\system.speech\6.0.0\lib\net6.0\System.Speech.dll
    std::string references = R"(-r:C:\Users\user\.nuget\packages\dotnetseleniumextras.waithelpers\3.11.0\lib\net45\SeleniumExtras.WaitHelpers.dll
    -r:C:\Users\user\.nuget\packages\naudio\2.1.0\lib\net6.0\NAudio.dll -r:/C:\Users\user\.nuget\packages\selenium.support\4.4.0\lib\net5.0\WebDriver.Support.dll
    -r:C:\Users\user\.nuget\packages\selenium.webdriver\4.4.0\lib\net5.0\WebDriver.dll -r:C:\Users\user\.nuget\packages\system.speech\6.0.0\lib\net6.0\System.Speech.dll)";
    std::string command = "mcs " + ProgramPath + ChromeInstPath + SeleniumWebPath + Mp3Path + references + R"( -target:library)";
    
    //Compile the script
    std::string Command = std::string(R"(cd C:\Program Files (x86)\Mono\bin && )") + command;
    system(Command.c_str());
#pragma endregion

#pragma region Init mono runtime
    mono_set_dirs("C:\\Program Files (x86)\\Mono\\lib",
        "C:\\Program Files (x86)\\Mono\\etc");

    //Init a domain
    MonoDomain* domain;
    domain = mono_jit_init("MonoScriptTry");
    if (!domain)
    {
        std::cout << "mono_jit_init failed" << std::endl;
        system("pause");
        return 1;
    }

    //Open a assembly in the domain
    MonoAssembly* assembly;
    std::string assemblyPath = std::filesystem::path(get_working_path()).parent_path().string() + R"(\CMonoTest\Program.dll)";
    assembly = mono_domain_assembly_open(domain, assemblyPath.c_str());
    if (!assembly)
    {
        std::cout << "mono_domain_assembly_open failed" << std::endl;
        system("pause");
        return 1;
    }

    //Get a image from the assembly
    MonoImage* image;
    image = mono_assembly_get_image(assembly);
    if (!image)
    {
        std::cout << "mono_assembly_get_image failed" << std::endl;
        system("pause");
        return 1;
    }
#pragma endregion

#pragma region Run a static method
    {
        //Build a method description object
        MonoMethodDesc* TypeMethodDesc;
        const char* TypeMethodDescStr = "Program:StartWebRegister()";
        TypeMethodDesc = mono_method_desc_new(TypeMethodDescStr, NULL);
        if (!TypeMethodDesc)
        {
            std::cout << "mono_method_desc_new failed" << std::endl;
            system("pause");
            return 1;
        }

        //Search the method in the image
        MonoMethod* method;
        method = mono_method_desc_search_in_image(TypeMethodDesc, image);
        if (!method)
        {
            std::cout << "mono_method_desc_search_in_image failed" << std::endl;
            system("pause");
            return 1;
        }

        //run the method
        std::cout << "Running the static method: " << TypeMethodDescStr << std::endl;
        mono_runtime_invoke(method, nullptr, nullptr, nullptr);
    }
#pragma endregion


#pragma endregion

    system("pause");
    return 0;
}

我试图使用 -r: 引用程序集,使用它们所在的完整路径,但它不起作用,我仍然得到错误。

  1. I Tried using msbuild, to build.csproj with instead of msc (see my other question Embedding mono in C++, Could not load file or assembly 'System.Runtime' or one of its dependencies ) but it cant call the static method

所以我的问题是如何引用程序集。 如果您使用的是 nuget,在 mono 中是否有一种简单的方法可以做到这一点? 我在文档上看到你可以使用 -pkg 调用包:如果它们有一个 .pc 文件(没有一个.nuget 有)

对于那些也有这个问题的人,我的问题是

std::string references = R"(-r:C:\Users\user\.nuget\packages\dotnetseleniumextras.waithelpers\3.11.0\lib\net45\SeleniumExtras.WaitHelpers.dll
    -r:C:\Users\user\.nuget\packages\naudio\2.1.0\lib\net6.0\NAudio.dll -r:C:\Users\user\.nuget\packages\selenium.support\4.4.0\lib\net5.0\WebDriver.Support.dll
    -r:C:\Users\user\.nuget\packages\selenium.webdriver\4.4.0\lib\net5.0\WebDriver.dll -r:C:\Users\user\.nuget\packages\system.speech\6.0.0\lib\net6.0\System.Speech.dll)";

不尊重这种格式

msc -r:"reference\to\assembly.dll"

即使路径没有任何空格,它也应该用引号引起来。
当您想使用完整路径时,这才是问题,因为

msc -r:System.Assembly.dll 

工作正常!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM