Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

173
Visualizações
Importación de un C# .NET 6.0 Core Dll en un C++ sin archivo TLB

Tengo un buen número de C# Dll que se crearon en .NET 4.6 Framework y necesito actualizarme a .NET Core 6; esa parte es relativamente sencilla. Sin embargo, esta biblioteca TAMBIÉN se usa dentro de una aplicación C++, a través de COM Interop. Esta opción era relativamente sencilla en .NET 4.6, porque en el momento de la compilación había una opción para exponer a COM Interop. Esto creó un archivo .tlb, que podría importarse directamente a la aplicación C++. Todo el ordenamiento necesario se realizó dentro del código C#: las matrices se pasaron como SafeArrays, etc. (consulte el ejemplo a continuación). Regasm.exe se ejecutó después del hecho para registrar el código C# necesario.

Con la actualización a .NET Core 6, se perdió la capacidad de crear un archivo .tlb en tiempo de ejecución. Sin embargo, (aparentemente) la interoperabilidad debería ser sencilla. He visto paquetes Nuget como DllExport (que tiene ejemplos poco claros para SafeArrays). He leído página tras página de las referencias de Microsoft sobre la interoperabilidad COM y el alojamiento COM, y he leído ejemplos relativos. Miré brevemente en el agujero del conejo de construir mi propio archivo .tlb. He visto muchos ejemplos personalizados que no se extienden a este problema exacto.

Aquí hay parte del código que estoy tratando de unir, como ejemplo para usted. ¿Qué tipo de cambios haría?

Código C# para importar

 public void CSharpMacro( [MarshalAs(UnmanagedType.SafeArray)] double[] D, [MarshalAs(UnmanagedType.SafeArray)] double[] O, [MarshalAs(UnmanagedType.SafeArray)] double[] H, [MarshalAs(UnmanagedType.SafeArray)] double[] L, [MarshalAs(UnmanagedType.SafeArray)] double[] C, [MarshalAs(UnmanagedType.SafeArray)] double[] V, [MarshalAs(UnmanagedType.LPStr)] string FilePath, [MarshalAs(UnmanagedType.SafeArray)] ref double[] sOutput, [MarshalAs(UnmanagedType.I8)] long CustNum, [MarshalAs(UnmanagedType.R8)] double TSDate) { String path = @"...\Errors.txt"; try { //some code } catch (Exception e) { //error handling } }

Ejemplo de importación de C++ (método actual): tenga en cuenta que se trata de una gran cantidad de código, pero el propósito es mostrarle cómo se importa el .tlb y cómo se usa el método de C# dentro del código, y algo de lo que sucede alrededor de eso. , como el uso de SafeArrays:

 // In the below import statement, use the location of the Release version of your C# DLL #import "...\PSP_CSLibrary.tlb" no_namespace //later in the code... (EasyObject is from external library, don't worry about it) void far __declspec(dllexport) __stdcall UMacro(EasyObject* pELObj, char* path) { // Initialize the COM interface HRESULT hr = CoInitialize(NULL); try { if (SUCCEEDED(hr) && pELObj != NULL) { // Init pointer to C# Library PSP_CSLibraryDLLClassPtr p(__uuidof(PSP_CSLibrary)); if (p != NULL) { int datanumber = 1; double *dOutput = new double[100]; for (int j = 0; j < 100; j++) dOutput[j] = 0; SAFEARRAY* sOutput = doubleToSA(dOutput, 100); EN_DATA_STREAM datastream = (datanumber == 1) ? pELObj->DataStream : GetDataStream(datanumber); double TSDate = pELObj->DateTimeMD[datastream]->AsDateTime[0]; long CustomerNumber = pELObj->Platform->CustomerID; int length = pELObj->CloseMD[datastream]->BarsBack; if (length > 0) { double *dDate = new double[length]; double *dOpen = new double[length]; double *dHigh = new double[length]; double *dLow = new double[length]; double *dClose = new double[length]; double *dVolume = new double[length]; // Load the double arrays with LEAST recent 0 for (int i = 0; i < length; i++) { dVolume[length - i - 1] = pELObj->VolumeMD[datastream]->AsDouble[i]; dOpen[length - i - 1] = pELObj->OpenMD[datastream]->AsDouble[i]; dHigh[length - i - 1] = pELObj->HighMD[datastream]->AsDouble[i]; dLow[length - i - 1] = pELObj->LowMD[datastream]->AsDouble[i]; dClose[length - i - 1] = pELObj->CloseMD[datastream]->AsDouble[i]; dDate[length - i - 1] = pELObj->DateTimeMD[datastream]->AsDateTime[i]; } // Convert to safe arrays from double arrays SAFEARRAY* sVolume = doubleToSA(dVolume, length); SAFEARRAY* sHigh = doubleToSA(dHigh, length); SAFEARRAY* sOpen = doubleToSA(dOpen, length); SAFEARRAY* sLow = doubleToSA(dLow, length); SAFEARRAY* sClose = doubleToSA(dClose, length); SAFEARRAY* sDate = doubleToSA(dDate, length); /////IMPORTANT PART if (sOpen != nullptr && sHigh != nullptr && sLow != nullptr && sOutput != nullptr && p != nullptr && sClose != nullptr && dOutput != nullptr) { p->CSharpMacro(sDate, sOpen, sHigh, sLow, sClose, sVolume, path, &sOutput, CustomerNumber, TSDate); } ///// // Release memory if (sDate != nullptr) SafeArrayDestroy(sDate); if (sVolume != nullptr) SafeArrayDestroy(sVolume); if (sOpen != nullptr) SafeArrayDestroy(sOpen); if (sHigh != nullptr) SafeArrayDestroy(sHigh); if (sLow != nullptr) SafeArrayDestroy(sLow); if (sClose != nullptr) SafeArrayDestroy(sClose); if (sOutput != nullptr) SafeArrayDestroy(sOutput); if (dDate != nullptr) delete[] dDate; if (dVolume != nullptr) delete[] dVolume; if (dOpen != nullptr) delete[] dOpen; if (dHigh != nullptr) delete[] dHigh; if (dLow != nullptr) delete[] dLow; if (dClose != nullptr) delete[] dClose; if (dOutput != nullptr) delete[] dOutput; } } p->Release(); } } catch (exception &e) { // did we get it? string out_ = "UMacro error= "; std::ostringstream strs; strs << e.what(); std::string str = strs.str(); out_ += str; appendLineToFile("PSP_Interface_Errors.txt", out_); } CoUninitialize(); return; }

Esta interacción, como se muestra arriba, funciona . ¿Alguien tiene ALGUNA idea sobre cómo continuar vinculando estos dos pero con C# en .NET Core 6? Preferiblemente con el mínimo esfuerzo. Me gustaría pensar que la mayor parte del trabajo ya está hecho, ya que los tipos ESTÁN organizados, como puede ver. ¿Cómo importo un C# Dll ahora, sin un archivo tlb?

Editar: como nota, esto debe estar en C++ no administrado . Actualmente estoy investigando el uso de una capa de interfaz C++/CLR y he obtenido un éxito moderado. Se actualizará si tiene éxito.

over 4 years ago · Santiago Trujillo
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda