I know this question has come up a lot of time in stackoverflow and I am posting this question after checking all the questions suggested by stackoverflow when I started this question.
Basically, I want to achieve this. Big picture: Pass an array of structs from c++ dll to a c# application. The catch here is that, the size of the array can only be determined by the c++ dll. Now I only know that getting an array of anything from c++ to c# is possible with the out parameter as a function argument. And yes, I can pass a ref to a c++ function as an out parameter whose size is not known but is initialized to NULL. But I am not sure if this is right or if it will work! And another way is, to get the array of structs as a return value, for which I didn't find any example in c#.
So what I did: Simplified this problem into a c++ problem:
I tried some sample examples to return an array of structs from a function to my main(), from a c++ dll to a test c++ application. --> Works fine. So as a return value, an array of structs works fine. Obviously, because I do not have to initialize my array of structs with the exact size, in the beginning before calling my function to populate the array!
But the catch is, I need to implement it in a way which will be feasible to be received by the c# end! So, as an out parameter to the function, and not as a return value (if anybody knows how to receive an array of structs from c++ dll to c#, please help!).
All the questions in stackoverflow or in google about passing an array of structs to a function have their size determined previously. But in my case, the function will only be able to decide the size. I do not know the size of the array prior to calling the function. And, I am really trying to complete the tasks in a single function call and hence, I cannot have 2 APIs, one for computing the size and one for getting the array. It would be a repetitive task since the same functionality has to be executed twice, once to only get the size and another time to get the actual array, which is not feasible!
I have a sample code. If anyone can help, it would be really appreciated.
// structsEx.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <conio.h>
#include <vector>
#include <string>
using namespace std;
using std::vector;
using std::string;
struct example
{
char* name; // char* or const char*. But not sure if I can have an
// std::string.
int age;
char* company;
};
void passStructsRef(struct example** ex) // Again, not sure if I can have
// std::array or std::vector since
// this will be the API I expose
// to C# side.
{
vector<string> names = {"AAA", "BBB", "CCC", "DDD", "EEE"};
vector<int> ages = {25, 26, 27, 28, 29, 30};
vector<string> companies = { "AAA1", "BBB2", "CCC3", "DDD4", "EEE5" };
*ex = new example[5]; // I think this is a problem. It only initializes
// the first element and hence, I get only the
// first item.
for (int i = 0; i < 5; i++)
{
ex[i] = new example(); // Is this right? Not sure..
ex[i]->age = ages[i];
ex[i]->name = _strdup(names[i].c_str());
ex[i]->company = _strdup(companies[i].c_str());
}
cout << "2 in function" << endl;
for (int i = 0; i < 5; i++)
{
cout << ex[i]->name << "\t" << ex[i]->age << "\t" << ex[i]->company << endl;
}
}
int main()
{
example ex;
ex.age = 30;
ex.name = "AEIOU";
ex.company = "ABCDE";
cout << "1" << endl;
cout << ex.name << "\t" << ex.age << "\t" << ex.company << endl;
cout << "2" << endl;
example *ex2 = nullptr;
passStructsRef(&ex2);
for (int i = 0; i < 5; i++)
{
cout << ex2[i].name << "\t" << ex2[i].age << "\t" << ex2[i].company << endl;
}
_getch();
return 0;
}
Following the comment, I think I have to give a bit of comments on my code. I am not sure if I can use STL arrays or vectors or std::string in my code which I am going to expose to C# application. Which is why I am using new operator here. Next question which might arise is where is delete? Well, I have to have another API calling delete to delete the memory allocated for the structure. Which will be called by my C# application when it has successfully received all the data I have returned and processed them. That is not a problem. But sending data to C# is a problem which has led me to write this sample C++ test application.
There is no big syntax or any special code to write to send data to C#. If it works in C++, it has to work in C#, if the parameters and APIs are exported properly. Which is why I am trying to get my C++ side perfect.
Hope this helps. Thanks a lot in advance.