Reputation: 55
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?
Upvotes: 3
Views: 1840
Reputation: 4614
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.
Upvotes: 1