2013-09-20 3 views
3

Мне нужно перейти от моего массива dll C++ к программе C#. Вот C++ код:C++ dll pass array to C#

__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; 
} 

Как вы можете видеть, есть функция, что сканирование файлов по типу. Он сохраняется в массиве строк и возвращается.

Теперь, вот C# код:

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

, а затем я звоню к этому методу:

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

Проблема заключается в том, что ничто не проходит в моей C программы # из Dll. Кто-нибудь может помочь с моей проблемой?

+0

Вы не можете вернуть 'std :: vector ' в C# land, и, конечно, не имеет смысла интерпретировать его как 'IntPtr'. Вы можете возвращать только базовые типы (не считая использования COM или CLI). Таким образом, вам нужно будет вернуть указатель на (не стек) память (возможно, 'char *', т. Е. Строки). –

+0

@EdS. Можете ли вы объяснить, как вернуть регулярный массив через C++ на C#? –

+0

http://www.pinvoke.net/ –

ответ

1

Вам нужно вернуть их не как вектор, а как примитивный тип, например, char **. Проблема в том, что для того, чтобы потреблять ее, вам нужно знать, сколько из них находится в коллекции. Как Эд. S в комментариях, вам может быть проще работать с CLI (если вы можете скомпилировать свой C++ с/clr). Но если вы можете это сделать, вы можете использовать типы .Net в C++ (например, List) и marshall your char*'s to Strings на стороне C++.

В противном случае вы можете вернуть необработанный символ char * на его стороне .Net. Чтобы использовать char * в C# (и, возможно, выполнив C++, вы будете чувствовать себя комфортно с этой функцией), вы можете использовать ключевое слово unsafe, чтобы вы могли конвертировать эти char * в System :: String в небезопасные и добавлять их к ваших коллекций .Net.

+0

Большое спасибо. У меня есть идея, как исправить это с вашим ответом .. –