List instead of array - c++-cli

I currently have a function with output myResult a dictionary of array of byte. I want to convert it into a dictionary of list of byte since for each entry I may store more than 1 array of byte. What is the format to replace the array with a list and how do I add each array to the list. The current format is the following:
int img_sz = img0->width * img0->height * img0->nChannels;
array <Byte>^ hh = gcnew array<Byte> (img_sz);
Marshal::Copy( (IntPtr)img->imageData, hh, 0, img_sz );
Dictionary<String^,array< Byte >^>^ myResult = gcnew Dictionary<String^,array< Byte >^>();
myResult["OVERVIEW"]=hh;
Any help is appreciated.

I'm not entirely sure which one of these you're going for, so I'll answer them both.
Dictionary<String^, List<Byte>^>^
If you want to end up with Dictionary<String^, List<Byte>^>^, just call the List<T> constructor that takes an IEnumerable<T>, and add it to the dictionary as you are now.
Dictionary<String^,List<Byte>^>^ myResult = gcnew Dictionary<String^,List<Byte>^>();
myResult["OVERVIEW"] = gcnew List<Byte>(hh);
Dictionary<String^, List<array<Byte>^>^>^
If you want to end up with Dictionary<String^, List<array<Byte>^>^>^, you'll need to check the dictionary to see if it as a list for that key yet, add the list if not, and then add the new array to the list. Call this method with the various arrays and name of the list you want to store each of them in.
void AddToResults(Dictionary<String^, List<array<Byte>^>^>^ myResult,
String^ key,
array<Byte>^ hh)
{
List<array<Byte>^>^ thisList;
if(!myResult->TryGetValue(key, thisList))
{
thisList = gcnew List<array<Byte>^>();
myResult->Add(key, thisList);
}
thisList->Add(hh);
}

Related

Remove Part of array in a For Loop

I am comparing two arrays, if the first array contains a word in the second array then it should delete it from the first array.
For Each word In array1
If array2.Contains(word) Then
array1.Remove(word)
End If
Next
However when I debug it gives me the following error:
Collection was modified; enumeration operation may not execute.
because its updating the array while its trying to iterate through it
Using Linq it could look like this. It filteres array1 by array2 and returns new array which contains only items from array1 which are not found in array2.
Public Function FilterArrayByArray() As String()
Dim array1() = New String() {"word1", "word2", "word3", "word4", "word5"}
Dim array2() = New String() {"word2", "word5"}
Return array1.Where(Function(array1Item) Not array2.Contains(array1Item)).ToArray()
End Function
I've seen this problem in C# before, assuming it's the same kind. In your example you are using a for each loop. Switch to a for loop (which has an index).
When a word is found that containsarray2.Contains(word), subtract one from the index.
E.G (C#),
for (int i = 0; i < array1.Count; i++) //iterate through the items in array1
{
if (array2.Contains(word) //if array2 contains word, ...
{
array1.Remove(word); //... then remove it, and subtract from i.
i--;
}
}
That or iterate through array1 backwards doing --i above. Both work fine.

How to pass variable length structure to pinvoke C function in C#

My C structure format is this:
typedef struct pt_data {
int Length; ///< Length of the Data field in bytes
uchar Data[1]; ///< The data itself, variable length
} PT_DATA;
My C function is this:
PT_STATUS PTSetFingerData (
IN PT_CONNECTION hConnection,
IN PT_LONG lSlotNr,
IN PT_DATA *pFingerData
)
Now I want to put a wrapper for this function in C#.
How can I do this? In particular, how can I do this for passing the C# PT_DATA struct to PT_DATA C struct?
You need to marshal the data manually. A variable length struct cannot be marshalled by the p/invoke marshaller.
In your case the obvious way to do this would be to declare the PTDATA* argument as byte[] in your p/invoke. Then you just need to populated the byte array before calling the function. The first 4 bytes are the length of the subsequent data.
static byte[] GetPTData(byte[] arr)
{
byte[] len = BitConverter.GetBytes(arr.Length);
byte[] data = new byte[sizeof(int) + arr.Length];
Array.Copy(len, data, sizeof(int));
Array.Copy(arr, 0, data, sizeof(int), arr.Length);
return data;
}

Create array of array in mq4

How to create a array of array in mq4?
I have a function with this pararameters:
double & v1[], double & v2[], double & v3[], double & v4[]
I want to create a array where each position has a reference to another array like:
double v[];
v[0] = v1;
v[1] = v2;
v[2] = v3;
v[3] = v4;
and then iterate like:
v[0][2] == v1[2]; // true
It's possible to do something like that? How can I do it?
You have pretty much already answered yourself already. A 2D array can be thought of/imagined as an array with each cell of the first array containing a 1D array of the specified size. Similarly, a 3D array could be imagined as a 1D array containing a 2D array in each cell. So instead of passing in v1,v2,v3,v4 you could just have the input parameter as double &v[4][6] and loop through them.
TestFunction(double &v[4][6])
{
for(int i=0;i<4;i++)
{
for(int j=0;j<6;j++)
{
v[i][j] = 0;
}
}
}
If the arrays v1,v2,v3,v4 in your example are different sizes then you could created an array of CArrayDouble objects and pass that. E.g.
CArrayDouble TestArray2[4]
void TestFunction2(CArrayDouble &v[4])
{
for(int i=0;i<4;i++)
{
for(int j=0;j<v[i].Total();j++)
{
v[i][j];
}
}
}
In answer to your comment, if you are unable to change the function signature. You could copy the arrays into an instance of CArrayDouble.
CArrayDouble ArrayOfArray[4];
ArrayOfArray[0].AssignArray(v1);
ArrayOfArray[1].AssignArray(v2);
ArrayOfArray[2].AssignArray(v3);
ArrayOfArray[3].AssignArray(v4);
If the arrays v1,v2 etc are buffers and thus change in size on every new bar, I would declare the CArrayDouble as static and after the initial copying (which is what AssignArray does), add each new element from the arrays as and when the function is called (using the member function 'Add').

XOR reverse a string in objective-c get an error

I want to use the following code to reverse a char * type string in objective-c:
- (char *)reverseString:(char *)aString
{
unsigned long length = strlen(aString);
int end = length - 1;
int start = 0;
while (start < end) {
aString[start] ^= aString[end];
aString[end] ^= aString[start];
aString[start] ^= aString[end];
++start;
--end;
}
return aString;
}
But I got an error EXC_BAD_ACCESS at this line
aString[start] ^= aString[end]
I googled and found people said I can't modify a literal string because it is readonly. I am new to C so I wonder what simple data type (no object) I can use in this example? I get the same error when I use (char []) aString to replace (char *) aString.
I assume you're calling this like
[myObj reverseString:"foobar"];
The string "foobar" here is a constant literal string. Its type should be const char *, but because C is braindead, it's char *. But it's still constant, so any attempt to modify it is going to fail.
Declaring the method as taking char[] actually makes no difference whatsoever. When used as a parameter type, char[] is identical to char*.
You have two choices here. The first is to duplicate the string before passing it to the method. The second is to change the method to not modify its input string at all but instead to return a new string as output. Both can be accomplished using strdup(). Just remember that the string returned from strdup() will need to be free()'d later.

how to get the size of the following array

int first[] = {1, 4};
int second[] = {2, 3, 7};
arrayOfCPointers[0] = first;
arrayOfCPointers[1] = second;
NSLog(#"size of %lu", sizeof(arrayOfCPointers[0]) / sizeof(int));
I want to have an array of sub arrays. Each sub array needs to be a different size. But I need to be able to find out the size of each sub array?
The Log keeps returning 1
You need to store the size somewhere. The language does not do so for bare C arrays. All you have is the address of the first element.
I'd write a wrapper class or struct to hold the array and it's metadata (like length).
typedef struct tag_arrayholder
{
int* pArray;
int iLen;
}ArrayHolder;
int first[] = {1, 4};
ArrayHolder holderFirst;
holderFirst.pArray = first;
holderFirst.iArrayLen = sizeof(first) / sizeof(int);
arrayOfCPointers[0] = holderFirst;
NSLog(#"size of %lu", arrayOfCPointers[0].iLen);
Or, like trojanfoe said, store special value marking the last position (exactly the approach zero-terminated string uses)
The "sizeof" instruction could be used to know the amount of bytes used by the array, but it works only with static array, with dynamics one it returns the pointer size. So with static array you could use this formula : sizeof(tab)/sizeof(tab[0]) to know the size of your array because the first part give you the tab size in bytes and the second the size of an element, so the result is your amount of element in your array ! But with a dynamic array the only way is to store the size somewhere or place a "sentinal value" at the end of your array and write a loop which count elements for you !
(Sorry for my English i'm french :/)
The NSLog statement is printing the value 1 because the expression you're using is dividing the size of the first element of the array (which is the size of an int) by the size of an int.
So what you currently have is this:
NSLog(#"size of %lu", sizeof(arrayOfCPointers[0]) / sizeof(int));
If you remove the array brackets, you'll get the value you're looking for:
NSLog(#"size of %lu", sizeof(arrayOfCPointers) / sizeof(int));
As other answers have pointed out, this won't work if you pass the array to another method or function, since all that's passed in that case is an address. The only reason the above works is because the array's definition is in the local scope, so the compiler can use the type information to compute the size.