CR_INIT **init_struct to C#
От: zamap  
Дата: 03.08.10 19:06
Оценка:
1. надо вызвать функцию cr_init. функция в dll сама выделяет память.
2. передать полседний параметр на вход cr_file_get_sign_struct- ref init_struct
Ошибок компиляции нет
cr_file_get_sign_struct function вот эта функция возвращает ошибку — как будто не верно в нее параметры передаются

ТКНИТЕ НОСОМ ГДЕ ОШИБКА В ПЕРЕДАЧЕ ПАРАМЕТРОВ

using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;


namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
my myclass = new my();
myclass.myfunction();
}

}
public class my
{
const int MASTER_KEY_LEN = 108;
const int ELG_KEY_LEN = 64 + 2;
const int TM_NUMBER_LEN = 8;
const int USER_ID_LEN = 256;
const int COMMENT_LEN = 256; // ???
const int SIGN_LEN = 64; // Pure Signature length, without User ID, its lenght and CRC.
const int HASH_LEN = 32;
const int ERR_NO_SIGN = 11;

struct CR_INIT
{
public IntPtr empty;
}

CR_INIT init_struct = new CR_INIT();
//CR_INIT init_struct = new CR_INIT();

IntPtr ptrparam = IntPtr.Zero;
//int DECL cr_init(int tm_flag, in
// const char *gk, in
// const char *uz, in
// const char *psw, in
// char *tm_number, out
// int *tmn_blen, in,out
// int *init_mode, out
// CR_INIT **init_struct ); out
[DllImport("Bicr_usr.dll")]
static extern int cr_init(
Int32 tm_flag,
string gk,
string uz,
string psw,
out string tm_number,
ref Int32 tmn_blen,
ref Int32 init_mode,
ref IntPtr init_struct);

//int DECL cr_uninit( CR_INIT *init_struct );
[DllImport("Bicr_usr.dll")]
static extern int cr_uninit(
IntPtr init_struct);

//int DECL cr_file_get_sign_struct (
// CR_INIT *init_struct, In
// const char *file_name, In
// int search_from, In
// void *sign, out
// int *sign_blen, In,out
// char *userid, out
// int *userid_blen, In,out
// int *struct_blen); out
//[DllImport("bicr_usr.dll")]
//unsafe public static extern int cr_file_get_sign_struct(ref CR_INIT glob_cr_init, string file_name, int search_from, object sign, int* sign_blen, string userid, int* ulen, int* struct_blen);
[DllImport("Bicr_usr.dll")]
static extern int cr_file_get_sign_struct(
ref CR_INIT init_struct,
[In] string file_name,
[In] Int32 search_from,
[In, Out] ref char[] sign,
[In, Out] ref Int32 sign_blen,
[In, Out] ref char[] userid,
[In, Out] ref Int32 ulen,
[In, Out] ref Int32 struct_blen);

public void myfunction()
{
Int32 init_mode = 0;
Int32 tmn_blen = 0;
int err = 0;
Int32 signblocklen = 0;
string h = "";


err = cr_init(0, null, null, "", out h, ref tmn_blen, ref init_mode, ref ptrparam);


// Marshal.PtrToStructure(ptrparam,init_struct);
init_struct = (CR_INIT)Marshal.PtrToStructure(ptrparam, typeof(CR_INIT));

// int t = Marshal.SizeOf(ptr);
// init_struct = (CR_INIT)Marshal.PtrToStructure(ptr, typeof(CR_INIT));

GetSignatureFromFile("C:\\86410061.xml", ref signblocklen);
}
Int32 _GetSignatureFromFile(ref CR_INIT init_struct, string file, Int32 search_from, ref char[] sign, Int32 maxsignlen, ref Int32 signlen, ref char[] userid, Int32 maxuidlen, ref Int32 uidlen, ref Int32 struct_blen)
{
int slen = maxsignlen;
int ulen = maxuidlen;

int err = cr_file_get_sign_struct(ref init_struct, file, search_from, ref sign, ref slen, ref userid, ref ulen, ref struct_blen);

if (Convert.ToBoolean(err)) return err;
signlen = slen;
uidlen = ulen;
return 0; // OK
}
public Int32 GetSignatureFromFile(string file, ref int signblocklen)
{
// InitializeCryptoLib();

char[] sign = new char[SIGN_LEN + 101];

Int32 signlen = 0;
char[] userid = new char[USER_ID_LEN + 1];

Int32 uidlen = 0;
Int32 struct_blen = 0;
Int32 err = 0;
Int32 search_from = 0;

for (; ; )
{
err = _GetSignatureFromFile(ref init_struct, file, search_from, ref sign, SIGN_LEN + 100, ref signlen, ref userid, USER_ID_LEN, ref uidlen, ref struct_blen);
if (Convert.ToBoolean(err))
{
if (err == ERR_NO_SIGN)
{
err = 0; // Its OK
signblocklen = search_from;
}
break;
}
search_from = search_from + struct_blen;
}
return err;
}

}
}
Re: CR_INIT **init_struct to C#
От: Аноним  
Дата: 04.08.10 06:59
Оценка:
Здравствуйте, zamap, Вы писали:

Насколько я понимаю, CR_INIT* это некий абстрактный handle (члены структуры в пользовательском коде не используются).
Поэтому в управляемом коде его объявлять не надо — там где функция в качестве параметра требует CR_INIT** передавать out IntPtr (или ref — по смыслу), где CR_INIT* — просто полученный IntPtr.

И при передаче строковых я бы везде добавил [MarshalAs(UnmanagedType.LPStr)] — вроде бы по умолчанию строки считаются юникодовыми, а сишная сторона явно хочет char*.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.