문제
저는 현재 이전 C++ 응용 프로그램과 상호 작용해야 하는 새 C# 프로젝트를 만드는 중입니다.C# 앱에서 사용해야 하는 C++ 앱에 이미 존재하는 오류 열거가 있습니다.
파일이 함께 업데이트되지 않으면 동기화 문제가 발생할 수 있으므로 C#에서 열거형을 다시 선언하고 싶지 않습니다..
내 질문은 다음과 같습니다.다음과 같이 선언된 열거형을 취할 수 있는 방법이 있습니까?
typedef enum
{
eDEVICEINT_ERR_FATAL = 0x10001
...
} eDeviceIntErrCodes;
다음과 같이 C# 프로그램에서 사용합니다.
eDeviceIntErrCodes.eDEVICEINT_ERR_FATAL
해결책
PInvoke Interop Assistant 도구를 확인하세요. http://www.codeplex.com/clrinterop/Release/ProjectReleases.aspx?ReleaseId=14120.기본 메서드에 대한 PInvoke 서명을 생성하는 데 유용한 도구입니다.
내가 당신의 열거형에 먹이를 주면 이 코드가 생성됩니다.도구의 명령줄 버전이 포함되어 있으므로 C++ 버전이 변경될 때마다 열거형의 C# 정의를 최신 상태로 유지하는 자동화된 프로세스를 구축할 수 있습니다.
public enum eDeviceIntErrCodes
{
/// eDEVICEINT_ERR_FATAL -> 0x10001
eDEVICEINT_ERR_FATAL = 65537,
}
다른 팁
C/C++에서는 열거형 정의가 포함된 .cs 파일을 #include할 수 있습니다.전처리기 지시문을 주의 깊게 사용하면 C#과 C 간의 구문 차이를 처리할 수 있습니다.
예:
#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
C# 프로젝트에서 조건부 컴파일 기호 "CSharp"를 설정하고 C/C++ 빌드 환경에 그러한 전처리기 정의가 없는지 확인하세요.
이렇게 하면 빌드 시 두 부분만 동기화된다는 점에 유의하세요.다른 빌드의 바이너리를 혼합하여 사용하면 보장이 실패합니다.
간단한 대답은 '아니요'일 것입니다.죄송합니다. 다시 선언하셔야 합니다.
그러나 과거에는 C++ 열거형을 enums.cs 파일의 C# 형식으로 가져오고 이를 빌드의 일부로 실행하여 모든 것이 동기화되는 스크립트를 작성했습니다.
열거형을 다음과 같이 선언한 경우:
namespace blah
{
enum DEVICE_ERR_CODES
{
eDEVICEINT_ERR_FATAL = 0x10001,
eDEVICEINT_ERR_OTHER = 0x10002,
};
}
그리고 다른 파일에서는:
DEVICE_ERR_CODES eDeviceIntErrCodes;
확장자를 .cs로 지정하고 열거형 파일의 이름을 지정하면 작동하게 할 수 있습니다.다음과 같이 참조할 수 있습니다.
DEVICE_ERR_CODES err = DEVICE_ERR_CODES.eDEVICEINT_ERR_FATAL;
C++/CLI에서 강력한 열거형을 정의하면 열거형 코드가 dll 메타데이터에 포함됩니다.따라서 C#에서는 열거형 코드를 사용할 수 있습니다.
public enum class eDeviceIntErrCodes: int
{
eDEVICEINT_ERR_FATAL = 0x10001
...
};