簡體   English   中英

將字符串從C#傳遞到C ++ DLL

[英]Passing string from c# to c++ dll

我試圖將字符串從C#傳遞到C ++ dll。 我在dll中收到的字符串是一些奇怪的字符。 這是我的代碼。

在C ++ dll中:

#include "stdafx.h"
#include <tlhelp32.h>
#include <tchar.h>
#include "ProcessCheckerDll.h"
#include <fstream>
#include <algorithm>
#include <iostream>
#include <stdio.h>
#include <psapi.h>
#include "Shlwapi.h"
#include <string>
#include <windows.h>


namespace ProcessCheck
{
string GetRunningProcessFromHierarchy(char* argStrRoot)
{ 
    char ch;
    printf("Reached here 1.");
    scanf_s("%c",&ch);

    std::string strRoot(argStrRoot,strlen(argStrRoot));
    printf_s("strRoot = %s",strRoot);
    std::ifstream input("d:\\filelist.txt");
    std::string line;

    printf("Reached here 2.");
    scanf_s("%c",&ch);

    //printf("cdsroot=%ls",strRoot);

    std::transform(strRoot.begin(), strRoot.end(), strRoot.begin(), ::tolower);
    std::vector<std::string> collection;
    string result="";


    printf("Reached here 3.");
    scanf_s("%c",&ch);

    HANDLE hProcessSnap=nullptr;
    HANDLE hProcess;
    PROCESSENTRY32 pe32;
    DWORD dwPriorityClass;


    while( std::getline( input, line ) )
    {
        //Get the file name from path
        std::wstring strPathFromTextFile = std::wstring(line.begin(), line.end());
        LPCWSTR absolutePathToFile = strPathFromTextFile.c_str();
        LPCWSTR onlyFileName = PathFindFileName(absolutePathToFile); 

        // Take a snapshot of all processes in the system.
        hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        if(hProcessSnap == INVALID_HANDLE_VALUE)
        {
            printf("Failed to get the snapshot of running processes");
            return result;
        }

        pe32.dwSize = sizeof(PROCESSENTRY32);

        // Retrieve information about the first process and exit if unsuccessful
        if(!Process32First(hProcessSnap, &pe32))
        {
            printf("Failed to get the first process from the list");
            CloseHandle(hProcessSnap);     // clean the snapshot object
            return result;
        }

        // Now walk the snapshot of processes, and display information about each process in turn
        do
        {
            LPCWSTR processFileName = pe32.szExeFile;

            if(lstrcmpi(onlyFileName,processFileName)==0)
            {
                //If file name is same, check if path starts with cdsroot
                HANDLE processHandle = NULL;
                TCHAR filePath[MAX_PATH];

                processHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pe32.th32ProcessID);


                if (processHandle != NULL)
                {
                    if (GetModuleFileNameEx(processHandle, NULL, filePath, MAX_PATH) == 0)
                    {
                        printf("\nFailed to get module filename.");
                    }
                    else
                    {
                        std::wstring w_str(filePath);
                        std::string absolutePath(w_str.begin(), w_str.end());
                        std::transform(absolutePath.begin(), absolutePath.end(), absolutePath.begin(), ::tolower);

                        printf_s("Absolute path = %s", absolutePath);
                        printf_s("Matching with cdsroot = %s",strRoot);
                        if(absolutePath.find(strRoot)==0)
                        {
                            std::wstring processName(processFileName);
                            std::string strProcess(processName.begin(),processName.end());
                            printf_s("\nROOT match for Process name = %s",strProcess);

                            if (std::find(collection.begin(), collection.end(), strProcess) == collection.end())
                            {
                                collection.push_back(strProcess);
                                printf_s("\nAdding to collection Process name = %s",strProcess);
                                result = result + strProcess + ";";
                            }
                        }
                    }
                    CloseHandle(processHandle);
                }
                else
                {
                    printf("\nFailed to open process.");
                }
            }
        }
        while(Process32Next(hProcessSnap, &pe32));
    }

    CloseHandle(hProcessSnap);
    printf("Returning result %s", result);
    scanf_s("%c",&ch);
    return result;
}
}

頭文件包含:

#include <stdexcept>
#include <vector>
using namespace std;

namespace ProcessCheck
{
extern "C" { __declspec(dllexport) string GetRunningProcessFromHierarchy(char* argStrRoot); }
}

C#中的代碼是:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;

namespace ProcCheckTest
{
class Program
{

    [DllImport("C:\\Users\\himanshu\\Documents\\Visual Studio 2012\\Projects\\ProcessCheck\\Release\\ProcessCheckerDll.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern string GetRunningProcessFromHierarchy([MarshalAs(UnmanagedType.LPStr)] string strRoot);

    static void Main(string[] args)
    {
        string strRoot = "C:\\test\\today_16.6";
        string returnValue = GetRunningProcessFromHierarchy(strRoot);
    }
}
}

我傳遞的字符串是“ C:\\ test \\ today_16.6”,但是當我在dll代碼中打印該字符串時,它會打印出奇怪的字符。 怎么了

主要問題似乎在這里:

printf_s("strRoot = %s",strRoot);

問題在於strRoot的類型為std::string但是格式字符串需要char* 更改為:

printf_s("strRoot = %s",strRoot.c_str());

或直接使用argStrRoot

您的另一個問題是函數的返回值。 當前,您返回std::string 您無法使用p / invoke來封送它。 您需要返回char* 更重要的是,編組器將在其作為返回值接收的指針上調用CoTaskMemFree 因此,您需要分配使用CoTaskMemAlloc返回的char*

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM