Ola' daniweb, long time no see.
I've been absent for a while, mostly due to not having any problems to ask about, but also because I got one of those annoying 'job' things ^_^.
Anyhow, I'm not terribly familiar with C# (being from c++ land), however I've got to use it to integrate some of my companies libraries with a VSTA project they are working on. Nothing to complicated, just creating wrapper classes to use the exported functions in their library DLL's in C#.
Anyway, I've been fine marshalling structures before in C# by using the typical
[dllimport("...")]
[marshalas.something] function(x,y,z)
approach, however i've hit a sticky one and wondered if anyone had some advice.
I've got one library that needs to be dynamically loaded (path not known until runtime, etc). To accomplish this I've eaten my google-cookies and come up with this solution (that works for most of the functions).
public class Interface
{
//dll static bindings
[DllImport("kernel32.dll", EntryPoint = "LoadLibraryA")]
static extern int LoadLibrary(
[MarshalAs(UnmanagedType.LPStr)] string lpLibFileName);
[DllImport("kernel32.dll", EntryPoint = "GetProcAddress")]
static extern IntPtr GetProcAddress(int hModule,
[MarshalAs(UnmanagedType.LPStr)] string lpProcName);
[DllImport("kernel32.dll", EntryPoint = "FreeLibrary")]
static extern bool FreeLibrary(int hModule);
int hModule = 0;
unsafe delegate uint Function_del();
IntPtr Function_ptr;
Function_del Function_Deligate;
public Interface()
{
//this bit gets the path from windows registry
CM3Path PathObj = new CM3Path();
string AppPath = PathObj.CM3PathString;
//end this bit <_<
string FullPath = "";
if (AppPath != "")
{
FullPath = AppPath + "CPIF_External_Bindings.dll";
hModule = LoadLibrary(FullPath);
}
else
{
hModule = 0;
}
//capture library handle
if (hModule != 0)
{
Function_ptr = GetProcAddress(hModule, "Function");
Function_Deligate = (Function_del)Marshal.GetDelegateForFunctionPointer(Function_ptr, typeof(Function_del));
}
}
}
So far it's been working fine, however there's one function that is proving to be an issue.
The C++ for this function is as follows (forgive the DLL_PUBLIC macro, it's cross platform see)
DLL_PUBLIC InterChange::DocCheck GetDocData(void*ptr ,unsigned int Data)
and the 'DocCheck' object is a structure defined as follows
struct DocCheck
{
uint32_t Size;
char UUID[36];
uint32_t InternalCRC;
uint32_t ExternalCRC;
};
The problem comes in that I can't simply mashal this return value into the C# structure as I did with static loading, So I'm somewhat confused as the correct way to import this function, or if I can at all.
what I want to do is something like this (though I'm aware this will not work):
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi), Serializable]
public unsafe struct DocCheck
{
public UInt32 Size;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 36)]
public fixed char UUID[];
public UInt32 InternalCRC;
public UInt32 ExternalCRC;
};
unsafe delegate [MarshalAs(UnmanagedType.LPStruct)]DocCheck GetDocData_del(void*ptr ,uint Data);
IntPtr GetDocData_ptr;
GetDocData_del GetDocData_Deligate;
GetDocData_ptr = GetProcAddress(hModule, "GetDocData");
GetDocData_Deligate = (GetDocData_del)Marshal.GetDelegateForFunctionPointer(GetDocData_ptr, typeof(GetDocData_del));
Object = GetDocData_Deligate(DataPointer, Index);
So, any much appreciated advice gal's and guys?