Pergunta
Atualmente estou trabalhando na criação de um novo projeto C# que precisa interagir com um aplicativo C++ mais antigo.Já existe uma enumeração de erro no aplicativo C++ que preciso usar no aplicativo C#.
Não quero apenas declarar novamente a enumeração em C# porque isso pode causar problemas de sincronização no futuro se os arquivos não forem atualizados juntos.
Tudo o que foi dito, minha pergunta é esta:Existe uma maneira de obter uma enumeração declarada assim:
typedef enum
{
eDEVICEINT_ERR_FATAL = 0x10001
...
} eDeviceIntErrCodes;
e use-o em um programa C# assim:
eDeviceIntErrCodes.eDEVICEINT_ERR_FATAL
Solução
Confira a ferramenta PInvoke Interop Assistant http://www.codeplex.com/clrinterop/Release/ProjectReleases.aspx?ReleaseId=14120.É uma ferramenta útil para gerar assinaturas PInvoke para métodos nativos.
Se eu alimentá-lo com seu enum, ele gerará esse código.Há uma versão de linha de comando da ferramenta incluída para que você possa construir um processo automatizado para manter a definição C# do enum atualizada sempre que a versão C++ for alterada.
public enum eDeviceIntErrCodes
{
/// eDEVICEINT_ERR_FATAL -> 0x10001
eDEVICEINT_ERR_FATAL = 65537,
}
Outras dicas
Em C/C++ você pode #incluir um arquivo .cs que contém a definição de enumeração.O uso cuidadoso de diretivas de pré-processador cuida das diferenças de sintaxe entre C# e C.
Exemplo:
#if CSharp
namespace MyNamespace.SharedEnumerations
{
public
#endif
enum MyFirstEnumeration
{
Autodetect = -1,
Windows2000,
WindowsXP,
WindowsVista,
OSX,
Linux,
// Count must be last entry - is used to determine number of items in the enum
Count
};
#if CSharp
public
#endif
enum MessageLevel
{
None, // Message is ignored
InfoMessage, // Message is written to info port.
InfoWarning, // Message is written to info port and warning is issued
Popup // User is alerted to the message
};
#if CSharp
public delegate void MessageEventHandler(MessageLevel level, string message);
}
#endif
Em seu projeto C#, defina um símbolo de compilação condicional "CSharp" e certifique-se de que essa definição de pré-processador não exista no ambiente de construção C/C++.
Observe que isso apenas garantirá que ambas as partes sejam sincronizadas no momento da construção.Se você misturar e combinar binários de compilações diferentes, a garantia falhará.
A resposta simples será não.Desculpe, você terá que declarar novamente.
No entanto, no passado, escrevi scripts para importar minhas enums C++ para um formato C# em um arquivo enums.cs e executá-lo como parte da compilação, dessa forma, tudo sincroniza.
Se você tivesse declarado o enum como:
namespace blah
{
enum DEVICE_ERR_CODES
{
eDEVICEINT_ERR_FATAL = 0x10001,
eDEVICEINT_ERR_OTHER = 0x10002,
};
}
e em outro arquivo:
DEVICE_ERR_CODES eDeviceIntErrCodes;
e nomeou o arquivo enum com uma extensão .cs, você poderá fazê-lo funcionar.Você faria referência a isso como:
DEVICE_ERR_CODES err = DEVICE_ERR_CODES.eDEVICEINT_ERR_FATAL;
Se você definir enum forte em C++/CLI, os códigos enum serão incluídos nos metadados da dll.Portanto, você pode usar códigos enum em C#.
public enum class eDeviceIntErrCodes: int
{
eDEVICEINT_ERR_FATAL = 0x10001
...
};