我对我的问题进行了很多研究,发现了许多与[如何从c#
传递字符串]相关的问题。至c
dll]:
但是他们都帮不了我。我喜欢以任何方式提出问题:
<小时/>简要说明:
我的c
功能在 c#
中正常工作就在我交换GetProcessIntegrityLevel
时参数(在 c
dll 和 c#
import-dll 中)来自:
-
BOOL GetProcessIntegrityLevel(DWORD dwPID, LPSTR szIntegrityLevel);
对于这个:
-
BOOL GetProcessIntegrityLevel(LPSTR szIntegrityLevel, DWORD dwPID);
在第一种状态下,我的程序正常工作并更改了 LPSTR szIntegrityLevel
但在第二,它不起作用并且 LPSTR szIntegrityLevel
对于任何 pid 都始终为空。
我创建了一个 c
我在其中声明了以下内容 c
获取 Integrity Level
的函数 通过 pid 的进程:
#define MAX_INTEGRITY_LEVEL_LENGTH 30
extern "C"
{
__declspec(dllexport) BOOL GetProcessIntegrityLevel(DWORD dwPID, LPSTR szIntegrityLevel);
}
C 函数实现:
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()
来 self 的c
dll 在 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()
返回true
但是integrityLevel
对于任何pid
,消息框中始终为空!!!
令人惊讶的是,当我交换 c
中的参数时函数,也在c#
中,它确实有效:
__declspec(dllexport) BOOL GetProcessIntegrityLevel(LPSTR szIntegrityLevel, DWORD dwPID);
这对我来说很奇怪。我还尝试过 MarshalAs(UnmanagedType.LPStr)]
但给我相同的结果。
最佳答案
在 C# 中,ulong
是 64 位类型。 PID 参数是 DWORD
,它是一个 32 位参数。
将 C# 参数声明从 ulong
更改为 uint
以解决问题。
关于c# - 将字符串从 c# 传递到 c dll 时的错误行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54071231/