将字符串从C#传递到C DLL时行为错误

时间:2019-01-07 09:01:14

标签: c# c winapi dllimport

我对我的问题进行了很多研究,发现了许多与[如何将字符串从c#传递到c dll ]有关的问题:

但是他们谁也帮不了我。我更喜欢问我的问题:


简要说明:
当我从以下位置交换c参数(在c# dll和GetProcessIntegrityLevel import-dll中)时,我的c函数在c#中正常工作: / p>

  1. BOOL GetProcessIntegrityLevel(DWORD dwPID, LPSTR szIntegrityLevel);

对此:

  1. BOOL GetProcessIntegrityLevel(LPSTR szIntegrityLevel, DWORD dwPID);

在第一种状态下,我的程序可以正常运行并更改LPSTR szIntegrityLevel,但是在第二种状态下,它无法正常工作,LPSTR szIntegrityLevel始终为空且没有任何pid。


我创建了一个c dll库,在其中我 声明了 以下获得{em> c的{​​{1}}函数< / em>通过pid进行处理:

Integrity Level

C函数实现:

#define         MAX_INTEGRITY_LEVEL_LENGTH                  30
extern "C"
{
    __declspec(dllexport) BOOL GetProcessIntegrityLevel(DWORD dwPID, LPSTR szIntegrityLevel);
}

因此,我从BOOL GetProcessIntegrityLevel(DWORD dwPID, LPSTR szIntegrityLevel) { BOOL bFlag = FALSE; // Return flag HANDLE hToken = INVALID_HANDLE_VALUE; // Token handle HANDLE hProcess = NULL; // Process handle BOOL bProcToken = FALSE; // OpenProcessToken() result BOOL bTokenInfo = FALSE; // GetTokenInformation() result DWORD dwLengthNeeded = 0; // Token information length DWORD dwError = ERROR_SUCCESS; // GetTokenInformation() last error DWORD dwIntegrityLevel = 0; // Integrity level PTOKEN_MANDATORY_LABEL pTIL = NULL; // Use as token information // Open the process hProcess = OpenProcess(MAXIMUM_ALLOWED | PROCESS_QUERY_LIMITED_INFORMATION, FALSE, dwPID); if (hProcess != NULL) { // Open process token bProcToken = OpenProcessToken(hProcess, TOKEN_QUERY, &hToken); if (bProcToken == TRUE) { // Get token information bTokenInfo = GetTokenInformation(hToken, TokenIntegrityLevel, NULL, 0, &dwLengthNeeded); if (bTokenInfo == FALSE) { dwError = GetLastError(); if (dwError == ERROR_INSUFFICIENT_BUFFER) { pTIL = (PTOKEN_MANDATORY_LABEL)LocalAlloc(0, dwLengthNeeded); if (pTIL != NULL) { // Get token information bTokenInfo = GetTokenInformation(hToken, TokenIntegrityLevel, pTIL, dwLengthNeeded, &dwLengthNeeded); if (bTokenInfo == TRUE) { // Get integrity level dwIntegrityLevel = *GetSidSubAuthority(pTIL->Label.Sid, (DWORD)(UCHAR)(*GetSidSubAuthorityCount(pTIL->Label.Sid) - 1)); if (dwIntegrityLevel <= SECURITY_MANDATORY_LOW_RID) { // Low Integrity StrCpyA(szIntegrityLevel, "Low"); } else if ((dwIntegrityLevel >= SECURITY_MANDATORY_MEDIUM_RID) && (dwIntegrityLevel < SECURITY_MANDATORY_HIGH_RID)) { // Medium Integrity StrCpyA(szIntegrityLevel, "Medium"); } else if ((dwIntegrityLevel >= SECURITY_MANDATORY_HIGH_RID) && (dwIntegrityLevel < SECURITY_MANDATORY_SYSTEM_RID)) { // High Integrity StrCpyA(szIntegrityLevel, "High"); } else if (dwIntegrityLevel >= SECURITY_MANDATORY_SYSTEM_RID) { // System Integrity StrCpyA(szIntegrityLevel, "System"); } else if (dwIntegrityLevel == SECURITY_MANDATORY_UNTRUSTED_RID) { // Untrusted integrity StrCpyA(szIntegrityLevel, "Untrusted"); } else { StrCpyA(szIntegrityLevel, "UnKnown"); } bFlag = TRUE; } LocalFree(pTIL); } } } // Close token handle CloseHandle(hToken); } // Close the process handle CloseHandle(hProcess); } return bFlag; } 中的GetProcessIntegrityLevel() dll中导入c,如下所示:

c#

然后像这样调用// Define function pointers for using of c dll functions [DllImport("ProcessesPropDll.dll",CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.Bool)] // Get integrity level static extern bool GetProcessIntegrityLevel(ulong dwPID, StringBuilder szIntegrityLevel); 中的函数:

c#

在这种状态下,当我运行程序时,// Integrity level StringBuilder integrityLevel = new StringBuilder(200); if(GetProcessIntegrityLevel(11684, integrityLevel) == true) { MessageBox.Show(integrityLevel.ToString()); } 返回GetProcessIntegrityLevel(),但是对于任何trueintegrityLevel在消息框中始终为空!!!!

‌令人惊讶的是,当我在pid函数和c函数中互换参数时,它确实起作用:

c#

这对我来说很奇怪。我也尝试了__declspec(dllexport) BOOL GetProcessIntegrityLevel(LPSTR szIntegrityLevel, DWORD dwPID); ,但给了我相同的结果。

1 个答案:

答案 0 :(得分:1)

在C#中,ulong是64位类型。 PID参数是DWORD,它是一个32位参数。

将C#参数声明从ulong更改为uint,以解决问题。