Marshalling Array of UInt64

M

Mike

Folks, I got this to works, but in a kludgy way. I am wondering if I
be more precise and direct with the cli:

The unmanaged (RPC) function is:

BOOL APIENTRY FileSearch(const char *s,
DWORD &n,
unsigned __int64 *&p);

I'm wrapping it in a C++/CLR "proxy" library with this:

static array<UInt64^>^ FileSearch(String^ s)
{
const char* psz = (const char*)(void*)Marshal::StringToHGlobalAnsi(s);
array<UInt64^>^ alist = {};
UInt64 *p = NULL;
DWORD count = 0;
if :):FileSearch(psz, count, p)) {
alist = gcnew array<UInt64^>(count);
for (DWORD i=0; i < count; i++) {
alist = p;
}
if (p) {
//************ TODO: caused fault. ***********
// Need to expose the rpc client released function
//::free(p);
//************ TODO: caused fault. ***********
}
}
Marshal::FreeHGlobal(IntPtr((void*)psz));
return alist;
}

In a VB.NET client, oddly, the managed signature returns as a
System.ValueType. So I painly figured out how to work with that with a
bitconverter function:

Dim data() As ValueType = FileSearch("MP3")
For Each v As ValueType In data
Dim fr As TSearchRecord = ToSearchRecord(v)
Console.WriteLine(" - area: {0} ref: {1}", fr.Area, fr.Ref)
Next

// VB.NET doesn't have a HIWORD/LOWORD concept?
Function ToSearchRecord(ByVal i64 As Long) As TSearchRecord
Dim b As Byte() = BitConverter.GetBytes(i64)
Dim rec As TSearchRecord
rec.Ref = BitConverter.ToUInt32(b, 0)
rec.Area = BitConverter.ToUInt32(b, 4)
Return rec
End Function

I guess the array<UInt64^>^ is not quite cli compliant. Correct?

Is there a more straight forward way?

Ideally, an int64 item is:

typedef struct tagTSearchRecord {
DWORD ref;
DWORD area;
} TSearchRecord;

So I tried to return this:

static array<TSearchRecord^>^ FileSearch(String^ s)

but the compiler did not like this. I think TSearchRecord needs to be
a managed class, but I don't know if I want this overhead allocated
per item.

Any tip, guidance? It would be greatly appreciated.

Thanks

--
 
A

Armin Zingler

Mike said:
Folks, I got this to works, but in a kludgy way. I am wondering if I
be more precise and direct with the cli:

The unmanaged (RPC) function is:

BOOL APIENTRY FileSearch(const char *s,
DWORD &n,
unsigned __int64 *&p);

I'm wrapping it in a C++/CLR "proxy" library with this:

static array<UInt64^>^ FileSearch(String^ s)


I only had a quick look. Isn't it

static array<UInt64>^ FileSearch(String^ s)

because UInt64 is not a reference type.



Armin
 
M

Mike

Armin said:
I only had a quick look. Isn't it

static array<UInt64>^ FileSearch(String^ s)

because UInt64 is not a reference type.

That works to expose a ULONG() array when used as a function.

I was wasting time with examples I seen such as where passing as a
parameter:

static bool FileSearch(String^s array<UInt64 *>^ list)

is not exposed. Using a class worked perfecly:

public ref class TSearchRecord {
public:
UInt32 ref;
UInt32 area;
// constructor
TSearchRecord()
{
area = 0;
ref = 0;
}
// constructor
TSearchRecord(UInt32 _area, UInt32 _ref)
{
area = _area;
ref = _ref;
}
};

static array<TSearchRecord^>^ FileSearch(String^ s)

But I am not sure if this overhead (a class per item) is a good idea
when result counts could be in the thousands.

thanks
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top