3

I have to pass from my C++ dll array to the C# program. Here is the C++ code:

 __declspec(dllexport) std::vector<std::string> __stdcall 
    getFilesByDirs
    (
        string directory, 
        std::string fileFilter, 
        bool recursively = true
    )
{
    int __ID = 0;
    std::vector<std::string> filesArray;

    if (recursively)
        getFilesByDirs(directory, fileFilter, false);

    directory += "\\";

    WIN32_FIND_DATAA FindFileData;
    HANDLE hFind = INVALID_HANDLE_VALUE;

    std::string filter = directory + (recursively ? "*" : fileFilter);

    hFind = FindFirstFileA(filter.c_str(), &FindFileData);

    if (hFind == INVALID_HANDLE_VALUE)
    {
        return filesArray;
    }
    else
    {
        if (!recursively)
        {
            if(isGoodForUs(directory + std::string(FindFileData.cFileName))) 
            {
                filesArray[__ID] = directory + std::string(FindFileData.cFileName);
                __ID ++;
            }
        }

        while (FindNextFileA(hFind, &FindFileData) != 0)
        {
            if (!recursively)
            {
                if(!isGoodForUs(directory + std::string(FindFileData.cFileName))) continue;
                filesArray[__ID] = directory + std::string(FindFileData.cFileName);
            }
            else
            {
                if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)>0 && FindFileData.cFileName[0]!='.')
                {
                    if(!isGoodForUs(directory + std::string(FindFileData.cFileName))) continue;
                    getFilesByDirs(directory + std::string(FindFileData.cFileName), fileFilter);
                }
            }
            __ID ++;
        }

        DWORD dwError = GetLastError();
        FindClose(hFind);
    }

    return filesArray;
}

As you can see, there is a function that scanning for files by type. It's saved in the string array and returning out.

Now, here is the C# code:

[DllImport(@"files.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern IntPtr getFilesByDirs(string path, string exns, bool rec=true);

and then i am calling to this method:

IntPtr a = getFilesByDirs("C:\\", "*.docx");

The problem is that nothing pass to my C# program from the Dll. Anyone can help with my issue?

4
  • You can't return a std::vector<std::string> to c# land, and it certainly wouldn't make sense to interpret it as an IntPtr. You can only return basic types (short of using COM or CLI). So, you'll need to return a pointer to (non-stack) memory (probably char*, i.e., strings). Commented Sep 20, 2013 at 20:40
  • @EdS. Can you explain how to return an regular array via C++ to C#? Commented Sep 20, 2013 at 20:41
  • pinvoke.net Commented Sep 20, 2013 at 20:42
  • Make sure you actually need to invoke this beast. If "isGoodForUs" is sufficiently short to implement in C# or can be invoked more easily on it's own, the rest of the C++ function can be expressed as a two-liner of inbuilt C# functions. Commented Sep 20, 2013 at 21:13

1 Answer 1

1

You need to return them not as a vector but as a primitive type, such as a char**. The problem here is that, in order to consume it you need to know how many are in the collection. As Ed. S said in the comments, you may find it easier to work with CLI (if you can compile your C++ with /clr on). But if you can do that, then you can use .Net types in C++ (such as List) and marshall your char*'s to Strings on the C++ side.

Otherwise, you can return the raw char*'s an handle it on the .Net side. To consume the char*'s in C# (and maybe having done C++, you will feel comfortable with this feature) you can use the unsafe keyword so you can convert those char*'s to System::String's in unsafe and add them to your .Net collections.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.