Need help with Vector parameter when invoking C dll from C#

G

Guest

The function that I'm trying to call through DLLImport has a parameter that
has a C code's vector's Itrator to a structure. I Have marshalled the
structure in C# but how do I do the C type vector's Iterator in C#? The
problem is in the next line and the rest of the code is just additional
information on what I'm doing. Thanks.
CUnityDS.DE_ERRORS errcode = CUnityDS.LibWrap.EncodeAsnUser(ref blob,
userContextData);


//In & out parameter for data structure for meetingBlob decoded data
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class CUserContextData
{
public int bWinLogOn = 0;
public int bUnifiedID = 0;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
MAX_ADSPATH_CHARS)]
public String shell = null;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
MAX_ADSPATH_CHARS)]
public String homeDir = null;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
MAX_ADSPATH_CHARS)]
public String primaryGroupSID = null;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
MAX_ADSPATH_CHARS)]
public String LoginName = null;

public int symarkUID = 0; //Unified User ID
public int IID = 0; //Independant ID
public int Revision = 0;
}

public class LibWrap
{
//import the dll that decodes the user meetingBlob
[DllImport("UnityDecodeAsnUser.dll", CharSet = CharSet.Unicode)]
public static extern DE_ERRORS DecodeAsnUser(ref Blob blob,
[In, Out]CUserContextData m);

[DllImport("UnityDecodeAsnUser.dll", CharSet = CharSet.Unicode)]
public static extern DE_ERRORS DecodeAsnGroup(ref Blob blob,
[In, Out]CGroupContextData m);

[DllImport("UnityDecodeAsnUser.dll", CharSet = CharSet.Unicode)]
public static extern DE_ERRORS EncodeAsnUser(ref Blob blob,
[In, Out]CUserContextData m);

CUnityDS.CUserContextData userContextData = new CUnityDS.CUserContextData();
//put data into struc userContextData
CUnityDS.DE_ERRORS errcode = CUnityDS.LibWrap.EncodeAsnUser(ref blob,
userContextData);
deNewContextObject.Properties["meetingBlob"].Add((object)blob);//got memory
corruption error here



int nBytes = Marshal.SizeOf(typeof(CUnityDS.Blob));
IntPtr ptr = Marshal.AllocHGlobal(nBytes);

// create an instance of the Blob structure
CUnityDS.Blob blob = new CUnityDS.Blob();

// copy and pin the structure to that location
Marshal.StructureToPtr(blob, ptr, true);

// Pass it by reference
// OK, now it's time to "reconsitute" the structure
blob = (CUnityDS.Blob)Marshal.PtrToStructure(ptr, typeof(CUnityDS.Blob));

//-------- This is the C code for the import method of the dll
extern "C" DE_ERRORS __declspec(dllexport)EncodeAsnUser(Blob** ppBlob,
vector <CUserContextData>::iterator userDataIter)
{
_bstr_t temp;
AsnData* pAsn;
//int boolInt;
std::wstring wsUID;


if ( ( pAsn = AsnAlloc( NULL ) ) == NULL )
{
DbgLog( DL_ERROR, "Unable to allocate ASN.1 buffer" );
return DE_MEMORY_ALLOCATION_FAILURE;
}
if ( !AsnPushTag(pAsn, (ASN_TAG$APPLICATION_START) ) )
goto failed;

if (!AsnWriteInteger( pAsn, REVISION))
goto failed;

if(userDataIter->bUnifiedID)//use UID
{
if (!AsnWriteInteger( pAsn, True) )
goto failed;
}
else //use indep ID
{
if (!AsnWriteInteger( pAsn, False) )
goto failed;
}
if(userDataIter->IID == NULL)
{
if ( !AsnWriteGeneralString( pAsn, EMPTY_STRING))
goto failed;
}
else
{
_bstr_t bstrtUID = L"0"; //initilize the bstr
_itow(userDataIter->IID, bstrtUID, 10);

if ( !AsnWriteGeneralString( pAsn, bstrtUID.operator const char *()))
goto failed;
}

//WinUser name
if(userDataIter->bWinLogOn)
{
if (!AsnWriteInteger( pAsn, True) )
goto failed;

}
else//use indep User Name
{
if (!AsnWriteInteger( pAsn, False) )
goto failed;
}

//Geco
if ( !AsnWriteGeneralString( pAsn, EMPTY_STRING))
goto failed;

//Shell
temp = userDataIter->shell.c_str();
if ( !AsnWriteGeneralString( pAsn, temp.operator const char *()))
goto failed;

//Home Driectory
temp = userDataIter->homeDir.c_str();
if ( !AsnWriteGeneralString( pAsn, temp.operator const char *()))
goto failed;

//Primary Group SID
temp = userDataIter->primaryGroupSID.c_str();
if (!AsnWriteGeneralString( pAsn, temp.operator const char *()))
goto failed;

if ( !AsnPopTag( pAsn ) )
goto failed;
*ppBlob = AsnExtractData( pAsn );
AsnFree( pAsn );
return DE_SUCCESS;

failed:
DbgLog(DL_ERROR, "Failed to encode ASN.1 message packet" );
AsnFree( pAsn );
return DE_ENCODE_MESSAGE_PACKET_FAILURE;
}
 
W

Willy Denoyette [MVP]

Pucca said:
The function that I'm trying to call through DLLImport has a parameter
that
has a C code's vector's Itrator to a structure. I Have marshalled the
structure in C# but how do I do the C type vector's Iterator in C#? The
problem is in the next line and the rest of the code is just additional
information on what I'm doing. Thanks.
CUnityDS.DE_ERRORS errcode = CUnityDS.LibWrap.EncodeAsnUser(ref blob,
userContextData);


//In & out parameter for data structure for meetingBlob decoded
data
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class CUserContextData
{
public int bWinLogOn = 0;
public int bUnifiedID = 0;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
MAX_ADSPATH_CHARS)]
public String shell = null;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
MAX_ADSPATH_CHARS)]
public String homeDir = null;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
MAX_ADSPATH_CHARS)]
public String primaryGroupSID = null;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
MAX_ADSPATH_CHARS)]
public String LoginName = null;

public int symarkUID = 0; //Unified User ID
public int IID = 0; //Independant ID
public int Revision = 0;
}

public class LibWrap
{
//import the dll that decodes the user meetingBlob
[DllImport("UnityDecodeAsnUser.dll", CharSet =
CharSet.Unicode)]
public static extern DE_ERRORS DecodeAsnUser(ref Blob blob,
[In, Out]CUserContextData m);

[DllImport("UnityDecodeAsnUser.dll", CharSet =
CharSet.Unicode)]
public static extern DE_ERRORS DecodeAsnGroup(ref Blob blob,
[In, Out]CGroupContextData m);

[DllImport("UnityDecodeAsnUser.dll", CharSet =
CharSet.Unicode)]
public static extern DE_ERRORS EncodeAsnUser(ref Blob blob,
[In, Out]CUserContextData m);

CUnityDS.CUserContextData userContextData = new
CUnityDS.CUserContextData();
//put data into struc userContextData
CUnityDS.DE_ERRORS errcode = CUnityDS.LibWrap.EncodeAsnUser(ref blob,
userContextData);
deNewContextObject.Properties["meetingBlob"].Add((object)blob);//got
memory
corruption error here



int nBytes = Marshal.SizeOf(typeof(CUnityDS.Blob));
IntPtr ptr = Marshal.AllocHGlobal(nBytes);

// create an instance of the Blob structure
CUnityDS.Blob blob = new CUnityDS.Blob();

// copy and pin the structure to that location
Marshal.StructureToPtr(blob, ptr, true);

// Pass it by reference
// OK, now it's time to "reconsitute" the structure
blob = (CUnityDS.Blob)Marshal.PtrToStructure(ptr, typeof(CUnityDS.Blob));

//-------- This is the C code for the import method of the dll
extern "C" DE_ERRORS __declspec(dllexport)EncodeAsnUser(Blob** ppBlob,
vector <CUserContextData>::iterator userDataIter)
{
_bstr_t temp;
AsnData* pAsn;
//int boolInt;
std::wstring wsUID;


if ( ( pAsn = AsnAlloc( NULL ) ) == NULL )
{
DbgLog( DL_ERROR, "Unable to allocate ASN.1 buffer" );
return DE_MEMORY_ALLOCATION_FAILURE;
}
if ( !AsnPushTag(pAsn, (ASN_TAG$APPLICATION_START) ) )
goto failed;

if (!AsnWriteInteger( pAsn, REVISION))
goto failed;

if(userDataIter->bUnifiedID)//use UID
{
if (!AsnWriteInteger( pAsn, True) )
goto failed;
}
else //use indep ID
{
if (!AsnWriteInteger( pAsn, False) )
goto failed;
}
if(userDataIter->IID == NULL)
{
if ( !AsnWriteGeneralString( pAsn, EMPTY_STRING))
goto failed;
}
else
{
_bstr_t bstrtUID = L"0"; //initilize the bstr
_itow(userDataIter->IID, bstrtUID, 10);

if ( !AsnWriteGeneralString( pAsn, bstrtUID.operator const char *()))
goto failed;
}

//WinUser name
if(userDataIter->bWinLogOn)
{
if (!AsnWriteInteger( pAsn, True) )
goto failed;

}
else//use indep User Name
{
if (!AsnWriteInteger( pAsn, False) )
goto failed;
}

//Geco
if ( !AsnWriteGeneralString( pAsn, EMPTY_STRING))
goto failed;

//Shell
temp = userDataIter->shell.c_str();
if ( !AsnWriteGeneralString( pAsn, temp.operator const char *()))
goto failed;

//Home Driectory
temp = userDataIter->homeDir.c_str();
if ( !AsnWriteGeneralString( pAsn, temp.operator const char *()))
goto failed;

//Primary Group SID
temp = userDataIter->primaryGroupSID.c_str();
if (!AsnWriteGeneralString( pAsn, temp.operator const char *()))
goto failed;

if ( !AsnPopTag( pAsn ) )
goto failed;
*ppBlob = AsnExtractData( pAsn );
AsnFree( pAsn );
return DE_SUCCESS;

failed:
DbgLog(DL_ERROR, "Failed to encode ASN.1 message packet" );
AsnFree( pAsn );
return DE_ENCODE_MESSAGE_PACKET_FAILURE;
}



Not sure what you are trying to achieve here, you are passing a structure to
a function who's expecting a stl::vector iterator (according it's function
signature), this can never work, but there is more, you aren't using this
parameter as iterator in the C++ code, so this will never compile.

Willy.
 
G

Guest

Hi Willy,
You're correct about this will not compile in C# correctly. I need help in
figuring out how to use and call this C++ function properly with the correct
paramenter type. The C++ function is
extern "C" DE_ERRORS __declspec(dllexport)EncodeAsnUser(Blob** ppBlob,
vector <CUserContextData>::iterator userDataIter)

I have the structure CUserContextData declare correctly in C# already. But
how do I use C# code to call this fucntion? I think the Blob** is declared
correctly but how do I declare a vector::iterator for the structure
CUserContextData as a parameter in C# to call this function? Thank you.
--
Thanks.


Willy Denoyette said:
Pucca said:
The function that I'm trying to call through DLLImport has a parameter
that
has a C code's vector's Itrator to a structure. I Have marshalled the
structure in C# but how do I do the C type vector's Iterator in C#? The
problem is in the next line and the rest of the code is just additional
information on what I'm doing. Thanks.
CUnityDS.DE_ERRORS errcode = CUnityDS.LibWrap.EncodeAsnUser(ref blob,
userContextData);


//In & out parameter for data structure for meetingBlob decoded
data
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class CUserContextData
{
public int bWinLogOn = 0;
public int bUnifiedID = 0;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
MAX_ADSPATH_CHARS)]
public String shell = null;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
MAX_ADSPATH_CHARS)]
public String homeDir = null;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
MAX_ADSPATH_CHARS)]
public String primaryGroupSID = null;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
MAX_ADSPATH_CHARS)]
public String LoginName = null;

public int symarkUID = 0; //Unified User ID
public int IID = 0; //Independant ID
public int Revision = 0;
}

public class LibWrap
{
//import the dll that decodes the user meetingBlob
[DllImport("UnityDecodeAsnUser.dll", CharSet =
CharSet.Unicode)]
public static extern DE_ERRORS DecodeAsnUser(ref Blob blob,
[In, Out]CUserContextData m);

[DllImport("UnityDecodeAsnUser.dll", CharSet =
CharSet.Unicode)]
public static extern DE_ERRORS DecodeAsnGroup(ref Blob blob,
[In, Out]CGroupContextData m);

[DllImport("UnityDecodeAsnUser.dll", CharSet =
CharSet.Unicode)]
public static extern DE_ERRORS EncodeAsnUser(ref Blob blob,
[In, Out]CUserContextData m);

CUnityDS.CUserContextData userContextData = new
CUnityDS.CUserContextData();
//put data into struc userContextData
CUnityDS.DE_ERRORS errcode = CUnityDS.LibWrap.EncodeAsnUser(ref blob,
userContextData);
deNewContextObject.Properties["meetingBlob"].Add((object)blob);//got
memory
corruption error here



int nBytes = Marshal.SizeOf(typeof(CUnityDS.Blob));
IntPtr ptr = Marshal.AllocHGlobal(nBytes);

// create an instance of the Blob structure
CUnityDS.Blob blob = new CUnityDS.Blob();

// copy and pin the structure to that location
Marshal.StructureToPtr(blob, ptr, true);

// Pass it by reference
// OK, now it's time to "reconsitute" the structure
blob = (CUnityDS.Blob)Marshal.PtrToStructure(ptr, typeof(CUnityDS.Blob));

//-------- This is the C code for the import method of the dll
extern "C" DE_ERRORS __declspec(dllexport)EncodeAsnUser(Blob** ppBlob,
vector <CUserContextData>::iterator userDataIter)
{
_bstr_t temp;
AsnData* pAsn;
//int boolInt;
std::wstring wsUID;


if ( ( pAsn = AsnAlloc( NULL ) ) == NULL )
{
DbgLog( DL_ERROR, "Unable to allocate ASN.1 buffer" );
return DE_MEMORY_ALLOCATION_FAILURE;
}
if ( !AsnPushTag(pAsn, (ASN_TAG$APPLICATION_START) ) )
goto failed;

if (!AsnWriteInteger( pAsn, REVISION))
goto failed;

if(userDataIter->bUnifiedID)//use UID
{
if (!AsnWriteInteger( pAsn, True) )
goto failed;
}
else //use indep ID
{
if (!AsnWriteInteger( pAsn, False) )
goto failed;
}
if(userDataIter->IID == NULL)
{
if ( !AsnWriteGeneralString( pAsn, EMPTY_STRING))
goto failed;
}
else
{
_bstr_t bstrtUID = L"0"; //initilize the bstr
_itow(userDataIter->IID, bstrtUID, 10);

if ( !AsnWriteGeneralString( pAsn, bstrtUID.operator const char *()))
goto failed;
}

//WinUser name
if(userDataIter->bWinLogOn)
{
if (!AsnWriteInteger( pAsn, True) )
goto failed;

}
else//use indep User Name
{
if (!AsnWriteInteger( pAsn, False) )
goto failed;
}

//Geco
if ( !AsnWriteGeneralString( pAsn, EMPTY_STRING))
goto failed;

//Shell
temp = userDataIter->shell.c_str();
if ( !AsnWriteGeneralString( pAsn, temp.operator const char *()))
goto failed;

//Home Driectory
temp = userDataIter->homeDir.c_str();
if ( !AsnWriteGeneralString( pAsn, temp.operator const char *()))
goto failed;

//Primary Group SID
temp = userDataIter->primaryGroupSID.c_str();
if (!AsnWriteGeneralString( pAsn, temp.operator const char *()))
goto failed;

if ( !AsnPopTag( pAsn ) )
goto failed;
*ppBlob = AsnExtractData( pAsn );
AsnFree( pAsn );
return DE_SUCCESS;

failed:
DbgLog(DL_ERROR, "Failed to encode ASN.1 message packet" );
AsnFree( pAsn );
return DE_ENCODE_MESSAGE_PACKET_FAILURE;
}



Not sure what you are trying to achieve here, you are passing a structure to
a function who's expecting a stl::vector iterator (according it's function
signature), this can never work, but there is more, you aren't using this
parameter as iterator in the C++ code, so this will never compile.

Willy.
 
W

Willy Denoyette [MVP]

Pucca said:
Hi Willy,
You're correct about this will not compile in C# correctly. I need help
in
figuring out how to use and call this C++ function properly with the
correct
paramenter type. The C++ function is
extern "C" DE_ERRORS __declspec(dllexport)EncodeAsnUser(Blob** ppBlob,
vector <CUserContextData>::iterator userDataIter)

I have the structure CUserContextData declare correctly in C# already.
But
how do I use C# code to call this fucntion? I think the Blob** is
declared
correctly but how do I declare a vector::iterator for the structure
CUserContextData as a parameter in C# to call this function? Thank you.
--


You can't call this function from C#, you can only pass an iterator from
C++. What you could do is implement a function in a C++ wrapper that takes
an array of type CUserContextData and convert this into a vector of type
CUserContextData, then you need to declare a vector iterator for this vector
and pass the iterator to the EncodeAsnUser function.

Willy.
 
G

Guest

Thanks Willy. I think maybe I'll try working on a new C code function
similar to the one with vector except that I would only need to pass in the
structure CUserContextData. This might be easier for me than the wrapper.
From C# I'm only encoding one user structure at a time and really don't need
the vector stuff. Thank you very much.
 

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