Vinculando DLL C ++ não gerenciado com DLL da biblioteca de classe C ++ gerenciada
-
25-09-2019 - |
Pergunta
Como na pergunta Criando C ++ simples. Wrapper. Passo a passo
Estou tentando usar as classes C ++ no .NET, mas estou tendo problemas para construir no Visual Studio (2008).
Eu tenho uma classe A não gerenciada (C ++ compilado com /CLR). Criei uma classe C ++/CLR 'Class1', que envolve A e com os delegados do método correspondente aos métodos de A.
Se eu incluir o arquivo de origem da unidade da classe A no projeto da biblioteca de classes para a classe1 (gerenciado), não tenho problemas, tudo links e funciona bem, mas tenho muitas classes não gerenciadas C ++, como A e estou tentando colocá -las em uma DLL e vincular isso que DLL para a biblioteca gerenciada (de invólucros de classe). [Na verdade, não vejo necessidade de vincular essas DLLs neste momento, mas o compilador parece estar exigindo, dando os mesmos erros mostrados abaixo.
Criei a biblioteca VisualC ++ / CLR / Class e adicionei minha classe C ++ (uma listada abaixo) e Build. [Eu usei as configurações padrão, mas nas configurações do vinculador do projeto, tentei a saída de registro com sim e não.] Não houve erros e o arquivo .dll foi criado.
Criei a biblioteca VisualC ++ / CLR / Class e criei a classe Wrapper 'Class1'. Usei todas as configurações padrão. De acordo com as propriedades do projeto, cliquei em 'Referências' 'Adicionar nova referência "e selecionei a DLL criada na primeira etapa.
Eu recebo erros de vinculador:
test_NET_library.obj : error LNK2028: unresolved token (0A000009) "public: int __thiscall Z::A::m1(int,int)" (?m1@A@Z@@$$FQAEHHH@Z) referenced in function "public: int __clrcall test_NET_library::Class1::m1(int,int)" (?m1@Class1@test_NET_library@@$$FQ$AAMHHH@Z)
test_NET_library.obj : error LNK2028: unresolved token (0A00000A) "public: int __thiscall Z::A::m2(int,int)" (?m2@A@Z@@$$FQAEHHH@Z) referenced in function "public: int __clrcall test_NET_library::Class1::m2(int,int)" (?m2@Class1@test_NET_library@@$$FQ$AAMHHH@Z)
test_NET_library.obj : error LNK2019: unresolved external symbol "public: int __thiscall Z::A::m1(int,int)" (?m1@A@Z@@$$FQAEHHH@Z) referenced in function "public: int __clrcall test_NET_library::Class1::m1(int,int)" (?m1@Class1@test_NET_library@@$$FQ$AAMHHH@Z)
test_NET_library.obj : error LNK2019: unresolved external symbol "public: int __thiscall Z::A::m2(int,int)" (?m2@A@Z@@$$FQAEHHH@Z) referenced in function "public: int __clrcall test_NET_library::Class1::m2(int,int)" (?m2@Class1@test_NET_library@@$$FQ$AAMHHH@Z)
C:\temp\test_Cpp_CLI\test_NET_library\Debug\test_NET_library.dll : fatal error LNK1120: 4 unresolved externals
Os mesmos erros como se eu remover o A.CPP no projeto de biblioteca da classe Wrapper (a opção que funciona). Não entendo por que a construção está tentando resolver externos em primeiro lugar, porque essa é uma biblioteca, não um programa.
Existe algo mais que preciso adicionar às propriedades do projeto da Biblioteca de Classe Wrapper ou registrar a DLL de classes não gerenciadas ou opções de compilador? Eu também preciso de um arquivo .lib para ir com a DLL? (Nenhum arquivo LIB aparece no diretório de destino dos projetos)
Eu ainda tenho que usar __declspec (dllexport) [pensou que era apenas para funções de estilo C não membros da classe.] Como na pergunta: Exportar classes não gerenciadas de uma DLL Visual C ++?Embora a biblioteca C ++ não gerenciada seja compilada com o CLR ativado.
(Eu também tentei compilar como uma biblioteca estática, mas não consigo descobrir como adicionar o arquivo .lib ao projeto da biblioteca da classe CLR).
Minha aula de teste é
namespace Z
{
class A
{
public:
int m1(int p1, int p2);
int m2(int p3, int p4);
};
};
com a implementação:
#include "A.h"
namespace Z
{
int A::m1(int p1, int p2) { return p1+p2; };
int A::m2(int p3, int p4) { return p3 * p4; };
};
E a classe de invólucro é
#pragma once
#include "../A.h"
using namespace System;
namespace test_NET_library {
public ref class Class1
{
private: Z::A *a;
public: Class1()
: a(new Z::A)
{}
public: inline int m1(int p1, int p2)
{ return a->m1(p1,p2);
};
public: inline int m2(int p3, int p4)
{return a->m2(p3,p4);
};
};
}
Conforme a pergunta: Criação de DLL de modo misto C ++/CLIEu também tentei:
#pragma managed(push, off)
#include "../A.h"
#pragma managed(pop)
E também esse empurrão gerenciado em torno de A.CPP.
ATUALIZAÇÃO: De acordo com a resposta do McDave, removi o /CLR Isso produziu uma DLL, agora como faço para disponibilizar essa DLL para o meu test_net_library?
Tentei referências/adicionar uma nova referência e selecionei a nova nova DLL; e recebi a mensagem "Não foi possível adicionar referência ao arquivo 'C: .. UnManaged_lib.dll' porque não é o .NET Assembly ou o Control ActiveX registrado.". A DLL foi adicionada à lista de arquivos do projeto, mas o compilador parece estar ignorando -o.
Eu tentei adicionar/existir item e selecionei a nova DLL. Mas os arquivos .dll não são um tipo de arquivo selecionável.
Solução
Com as poucas dicas da sua atualização, tentarei duas suposições ...
- Quando o UnManaged_lib é um LIB estaticamente vinculado, você definiu o projeto não gerenciado_lib como uma dependência de test_net_library? (Na janela do Project Explorer, clique com o botão direito do mouse em test_net_library, selecione "Dependências do projeto ..." e selecione UNMANAGED_LIB.)
- Quando o UnManaged_lib é uma DLL, você precisa exportar a classe da DLL seguindo isto Responda e também faça com que o test_net_library dependa do projeto não gerenciado_lib.