Я пытаюсь создать аддон в nodejs, используя CMAKE. Файл CPP имеет очень базовую зависимость c, созданную мной в CSharp, классе, который должен вызываться из CPP. Когда я выполняю эту операцию в консольном приложении CPP, скомпилированном с Visual Studio, все работает правильно. Проблема возникает, когда я делаю компиляцию с CMAKE- JS, чтобы затем создать аддон узла, когда он должен вызвать метод в dll сборки, который я создал в Csharp, он говорит мне, что указанный файл не найден .
Это моя библиотека классов в CSharp, которая выводит файл с именем writeText.dll (Framework Framework 4.8)
writeText.cs
using System;
using System.Linq;
namespace writeText
{
public class CsTemplate
{
public string string1;
public string string2;
private static CsTemplate oInstance;
public CsTemplate()
{
}
/**
* @method Instance
*
* Singleton
*
* @returns {CsRecognizer} Clase instanciada.
*/
public static CsTemplate Instance()
{
if (oInstance == null)
{
oInstance = new CsTemplate();
}
return oInstance;
}
/**
* @method setString
*
* Asign values to properties
*
* @returns {CsRecognizer} Clase instanciada.
*/
public string setString(string str1, string str2)
{
string1 = str1;
string2 = str2;
return "El se asigna como " + string1 + " y la gramática se asignaa como " + string2;
}
}
}
Это файл Cpp, в котором используется зависимость, созданная в Csharp
main. cpp
#include <node_api.h>
#include <assert.h>
using namespace writeText;
namespace myaddon
{
#pragma managed
void callManaged()
{
System::String^ result = gcnew System::String("hello");
System::Console::WriteLine("It works: " + result);
}
void CallCsharp()
{
System::String^ str1Cpp = gcnew System::String("Uno");
System::String^ str2Cpp = gcnew System::String("Dos");
System::Console::WriteLine("String definidos: " + str1Cpp + " -> " + str2Cpp);
CsTemplate::Instance()->setString(str1Cpp, str2Cpp);
}
void printResults() {
System::Console::WriteLine("Defined strings: " + CsTemplate::Instance()->string1 + " -> " + CsTemplate::Instance()->string2);
}
#pragma unmanaged
napi_value Test(napi_env env, napi_callback_info info) {
napi_status status;
napi_value response;
callManaged();
status = napi_create_string_utf8(env, "OK", NAPI_AUTO_LENGTH, &response);
assert(status == napi_ok);
return response;
};
napi_value SetStrings(napi_env env, napi_callback_info info) {
napi_status status;
napi_value response;
CallCsharp();
status = napi_create_string_utf8(env, "OK", NAPI_AUTO_LENGTH, &response);
assert(status == napi_ok);
return response;
};
napi_value PrintStrings(napi_env env, napi_callback_info info) {
napi_status status;
napi_value response;
printResults();
status = napi_create_string_utf8(env, "OK", NAPI_AUTO_LENGTH, &response);
assert(status == napi_ok);
return response;
};
#define DECLARE_NAPI_METHOD(name, func) { name, 0, func, 0, 0, 0, napi_default, 0 }
napi_value Init(napi_env env, napi_value exports) {
napi_status status;
napi_property_descriptor listen = DECLARE_NAPI_METHOD("test", Test);
status = napi_define_properties(env, exports, 1, &listen);
assert(status == napi_ok);
napi_property_descriptor set = DECLARE_NAPI_METHOD("set", SetStrings);
status = napi_define_properties(env, exports, 1, &set);
assert(status == napi_ok);
napi_property_descriptor print = DECLARE_NAPI_METHOD("print", PrintStrings);
status = napi_define_properties(env, exports, 1, &print);
assert(status == napi_ok);
return exports;
}
NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)
}
Это мои списки CmakeLists .txt, который компилирует nodejs аддон
CmakeLists.txt
cmake_minimum_required(VERSION 3.17)
project (my-addon CXX CSharp)
include_directories(${CMAKE_JS_INC})
file(GLOB SOURCE_FILES "src/*.cpp")
add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES})
target_compile_options(${PROJECT_NAME} PRIVATE /clr)
target_compile_options(${PROJECT_NAME} PRIVATE /fp:precise) #/fp:strict is incompatible with /clr
set_property(TARGET ${PROJECT_NAME} PROPERTY VS_GLOBAL_ROOTNAMESPACE ${PROJECT_NAME})
set_property(TARGET ${PROJECT_NAME} PROPERTY VS_GLOBAL_KEYWORD "ManagedCProj")
set_property(TARGET ${PROJECT_NAME} PROPERTY VS_GLOBAL_CLRSupport "true")
set_property(TARGET ${PROJECT_NAME} PROPERTY DOTNET_TARGET_FRAMEWORK_VERSION "4.8")
set_property(TARGET ${PROJECT_NAME} PROPERTY VS_GLOBAL_WindowsTargetPlatformVersion "10.0.18362.0")
set_property(TARGET ${PROJECT_NAME} PROPERTY VS_DOTNET_REFERENCES_COPY_LOCAL "true")
set_property(TARGET ${PROJECT_NAME} PROPERTY VS_DOTNET_REFERENCES
"System"
)
# Add reference writeText.dll (This dll is writeText.cs compiled)
set_property(TARGET ${PROJECT_NAME} PROPERTY VS_DOTNET_REFERENCE_writeText "src/writeText.dll")
set_target_properties(${PROJECT_NAME} PROPERTIES
PREFIX ""
SUFFIX ".node"
COMMON_LANGUAGE_RUNTIME ""
)
target_include_directories(${PROJECT_NAME}
PRIVATE ${CMAKE_SOURCE_DIR}/node_modules/node-addon-api
PRIVATE ${CMAKE_JS_INC})
target_link_libraries(${PROJECT_NAME}
PUBLIC
${CMAKE_JS_LIB}
)
Как только это будет сделано, все прекрасно скомпилируется, в результате чего build / Освободите папку следующим образом:
Сборка Struct / образ выпуска
Кажется, все правильно, аддон создан отлично, и writeText.dll скопирован внутрь папка build / Release как положено.
Тогда я использую аддон
main. js
var addon = require('bindings')('my-addon');
console.log("Test: " + addon.test());
console.log("Set: " + addon.set());
console.log("Print: " + addon.print());
И я получаю это
$ node main.js
It works: hello
Test: OK
Unhandled Exception: System.IO.FileNotFoundException: Could not load file or
assembly 'writeText, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system could not find especified file
on myaddon.CallCsharp()
В test вызове метода все работает нормально и выводит на экран, используя пространство имен System, но когда вызывается метод set , использующий мой файл writeText.dll, он сообщает, что файл не найден.
Как вы можете видеть на изображении структуры вывода, файл там. Кроме того, когда я открываю проект, созданный CMake в Visual Studio, сборка кажется правильной.
Это структура проекта, созданного Cmake:
Project Cmake Struct
Кажется, все правильно, и в принципе все должно работать нормально, но по какой-то причине оно говорит мне, что writeText не может быть найден.