c/front dll calling from within manganed c# code

sjohannsjohann Member Posts: 2
edited 2004-09-14 in Navision Attain
First: We know the the .net wrapper class provided in the download section.
But because of the OCX Call Interface is very slow we are trying to connect our application via the cfront.dll to navsion.
The casting-problems with ref object-Parameters in DBL_GetFieldData() and DBL_AssignField() are soved by come methods using the DBL_FieldType()-Function to estimate the right type casting.

But we have problems with some other functions:

The attemp to call DBL_Field_2_Str() always causes a "System.NullReferenceException". The function is defiend in c# as:
[DllImport("cfront.dll",  SetLastError = true) ]
		protected static extern void DBL_Field_2_Str(
			[MarshalAs(UnmanagedType.LPStr)]
			out string Str, int StrSize, 
			int	hTable, int hRec, int FieldNo);

Another function, DBL_FieldName() causes this error not always, but on several fields:
[DllImport("cfront.dll",  SetLastError = true) ]
		[return: MarshalAs(UnmanagedType.LPStr)]
		protected static extern string DBL_FieldName( int hTable, int FieldNo);

Has anyone an idea, why this errors occur?
Thanks for your support from Solingen, Germany...
greets,
Sven

Comments

  • emilio.torrensemilio.torrens Member Posts: 3
    Hi,

    Try to use a StringBuilder and not a string in the DBL_Field_2_Str function, I've solved some similar problems using the StringBuilder

    In the DBL_FieldName I use a IntPtr in order to receive the name of the field:

    [DllImport("cfront.dll", EntryPoint="DBL_FieldName")] unsafe private static extern IntPtr DBL_FieldName(int* hTable, int FieldNo);
    unsafe internal string FieldName(int* hTable, int FieldNo)
    {
    return this.Oem2Char(Marshal.PtrToStringAnsi(DBL_FieldName(hTable, FieldNo)));
    }

    Best Regads, Emilio
  • fkofko Member Posts: 5
    Hi Emilio,

    is it posible to post some snipets of code, how you are working with this StringBuilder, and the OEM2CHAR function?

    I also have great troubles with .NET DateTime format and C/FRONT Date format. Have you any solution for this?

    Thanks in advance.
  • emilio.torrensemilio.torrens Member Posts: 3
    Hi,

    You have to convert the strings before to write in the database
    [DllImport("user32.dll")] private  static extern bool CharToOem(System.Text.StringBuilder lpszSrc, System.Text.StringBuilder lpszDst);
    [DllImport("cfront.dll", EntryPoint="DBL_AssignField")] unsafe private static extern void DBL_AssignFieldAsString(int* hTable, int* hRecord, int FieldNo, short FieldType,string Value, int Len);
    
    protected string Char2Oem(string data)
    {
    			System.Text.StringBuilder str = new System.Text.StringBuilder(data);
    			System.Text.StringBuilder str2 = new System.Text.StringBuilder(data.Length);
    			CharToOem(str,str2);
    			return str2.ToString();
    }
    
    
    unsafe protected void SetFieldValueAsText(int* hTable, int* hRecord, int FieldNo,string FieldValue) 
    {					
    FieldValue = this.Char2Oem(FieldValue);
    DBL_AssignFieldAsString(hTable, hRecord,FieldNo, DBL_FieldType(hTable,FieldNo),FieldValue ,DBL_FieldLen(hTable,FieldNo));			
    }
    		
    

    I also use the string builder in this function:
    [DllImport("cfront.dll")] unsafe private static extern void DBL_Field_2_Str(ref System.Text.StringBuilder Str, int StrSize, int* hTable, int* hRec, int FieldNo);
    
    


    I solve the problem with the DateTime with this codes:

    ReadData:
    [DllImport("cfront.dll")] unsafe private static extern void DBL_Date_2_YMD(ref void* y,ref void* m,ref void* d, ref bool Closing, long Date);
    
    		unsafe internal DateTime GetFieldValueAsDate(int* hTable,int* hRecord, int FieldNo, ref bool closing)
    
    		{
    			
    			if (!this.FieldIsEmpty(hTable,hRecord,FieldNo))
    			{	
    			
    				long* data = (long*) DBL_GetFieldDataAddr(this.hDBL_GetFieldDataAddr,hTable,hRecord,FieldNo);
    				void* d=null ,m=null ,y=null;
    				try
    				{
    					DBL_Date_2_YMD(ref y,ref m,ref d, ref closing,*data);
    					IntPtr handle = new IntPtr(y);
    					int Year = handle.ToInt32();
    					if (Year == 0) Year = 1;
    					handle = new IntPtr(m);
    					int Month = handle.ToInt32();
    					handle = new IntPtr(d);
    					int Day = handle.ToInt32();					
    					handle = IntPtr.Zero;
    					DateTime result = new DateTime(Year,Month,Day);
    					return result;
    				}
    				catch (Exception)
    				{
    					this.AddError(this.LastMessage ,false);
    					return new DateTime();
    				}
    				finally
    				{
    					data = null;
    					d = null;
    					m = null;
    					y = null;
    				}
    			}			   
    			else
    			{
    				DateTime result = new DateTime();
    				return result;
    			}
    


    Write Data:

    [DllImport("cfront.dll", EntryPoint=DBL_AssignField")] unsafe private static extern void DBL_AssignFieldAsDate(int* hTable, int* hRecord, int FieldNo, short FieldType,long* Value, int Len);
    
    [DllImport("cfront.dll")] unsafe private static extern void DBL_YMD_2_Date(ref long Date, int y, int m, int d, bool Closing);
    
    
    		unsafe internal void SetFieldValueAsDate(int* hTable, int* hRecord, int FieldNo,DateTime FieldValue,bool closing) 
    		{
    			int Year,Month,Day;
    			Year = FieldValue.Year;
    			Month = FieldValue.Month;
    			Day = FieldValue.Day;
    			if (Year != 1) //Si es 1 es que la fecha es 1/1/1 que para Navision es fecha en blanco
    			{
    				long data = 0;
    				DBL_YMD_2_Date(ref data,Year,Month,Day,closing);
    				DBL_AssignFieldAsDate(hTable, hRecord,FieldNo, DBL_FieldType(hTable,FieldNo),&data,DBL_FieldLen(hTable,FieldNo));			
    			}
    		}
    
    

    the same for Time Fields but with the DBL_Time_2_HMST function

    Best Regards
    
                            
  • phnagelphnagel Member Posts: 2
    Hi,

    I had a lot of things working (everything i needed actually), using the cfront.dll from c#.

    But since I installed the new servicepack (1.1 sp1) for .NET, i keep getting errors. The errors occur when calling the first function after init, setnavisionpath(..).

    One error is "module 1 error 182". Another one is (translated from dutch, so may differ from the english version) : "The operating system was unable to load the DLL module: . Check if this DLL-module exists. Also check if the other used DLL-modules exist."

    So it seems that somewhere it tries to load a dll with name "" (i.e. empty string). Has anyone experienced the same problem, can anyone give me a clue about this? What has changed in .NET and could cause this problem?

    Thanks,
    Peter
  • emilio.torrensemilio.torrens Member Posts: 3
    Hi

    I had the same problem, I found a solution in:

    http://dotnet247.com/247reference/msgs/35/177214.aspx

    the way is to call the CFRONT code in a new thread:
    	
    
    public void GetCustomers()
    {			
    
    System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(GetCustomers2));
    t.ApartmentState = System.Threading.ApartmentState.STA;
    t.Start();
    			
    }
    
    public void GetCustomers2()
    {
      //Put here your CFRONT code 
    }
    
    
    


    Salu2, Emilio
Sign In or Register to comment.