pulling hair out trying to get c# -> cfront.dll working

scusackscusack Member Posts: 6
edited 2004-06-16 in Navision Attain
Hi all,

I see that other people are also looking at using the cfront.dll functions from within c#, I also been playing with this.

From what I have read here and elsewhere I think the following code should work. However I am getting;

"Internal Error 182 in module 1."

According to WinHelp 182L is ERROR_INVALID_ORDINAL, according to some Nav stuff I read module 1 errors are Win32 errors, but I may be wrong on this.

I have compiled and run the C sample and I have also done some other C programs that don't have a problem.

Does anybody have any ideas?
using System;
using System.Runtime.InteropServices;

class MainClass
{
	[DllImport("user32.dll")] private  static extern bool CharToOem(System.Text.StringBuilder lpszSrc, System.Text.StringBuilder lpszDst);
	protected static 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();
	}

	[DllImport( "cfront.dll", CallingConvention = CallingConvention.Cdecl)]
	private static extern Int32 DBL_Init();

	[DllImport("cfront.dll", CallingConvention = CallingConvention.Cdecl)]
	private static extern void DBL_Exit();
	
	[DllImport("cfront.dll", CallingConvention = CallingConvention.Cdecl)]
	private static extern Int32 DBL_GetVersion();
		
	[DllImport("cfront.dll", CallingConvention = CallingConvention.Cdecl)]
	private static extern void DBL_ConnectServer( string server_name, string net_type );	
	private static void ConnectServer( string server, string net_type )
	{
		string _server   = Char2Oem( server   );
		string _net_type = Char2Oem( net_type );
		DBL_ConnectServer( _server, _net_type );
	}
	
	public static void Main(string[] args)
	{
		Console.WriteLine("Testing C/Front");
		DBL_Init();
		Console.WriteLine( "Version {0}", DBL_GetVersion() );		
		DBL_ConnectServer( "192.168.0.10", "TCP" );		
		DBL_Exit();	
	}
}

I am using .NET 1.1 and Windows 2000 if that makes any difference.

Comments

  • scusackscusack Member Posts: 6
    Just to keep anybody interested updated...

    I decided that maybe it wasn't the cfront.dll that was missing a related dll but maybe something that .NET was looking for so I compiled the code above using Portable.NET (http://www.dotgnu.org) and Mono (http://www.go-mono.org) and ran it using the respective interpreters and presto it worked! I connected looped through tables, read Company names, all without a problem.

    Just for an experiment I used the other interpreters to run the above example compiled by the other compilers Mono an PNET played nice together but each time I tried the Microsoft .NET runtime it complained about the "Internal Error, etc".

    Could somebody else compile and run the above example so I can work out if it is my installation of .NET that is the problem.

    This is unlikely as this problem exists on at least 3 computers that I have tried it on.

    I have tried it on :

    WinXP professional, WinXP Home, Win2000 all with the SDK and Runtime environments installed.

    I am not using Visual Studio so maybe VS installs something that is missing in the SDK or Runtime.

    Any help would be greatly appreciated.

    Regards, Simon.
  • scusackscusack Member Posts: 6
    Here is the latest example that I am working on, again it works fine in PNET and Mono but internal error, etc in .NET

    Could some one try and compile this one? and run it on .NET and post the results, it would be greatly appreciated.
    using System;
    using System.Runtime.InteropServices;
    
    class MainClass
    {
    	[DllImport( "cfront.dll", CallingConvention = CallingConvention.Cdecl)]
    	private static extern Int32 DBL_Init();
    
    	[DllImport("cfront.dll", CallingConvention = CallingConvention.Cdecl)]
    	private static extern void DBL_Exit();
    	
    	[DllImport("cfront.dll", CallingConvention = CallingConvention.Cdecl)]
    	private static extern Int32 DBL_GetVersion();
    		
    	[DllImport("cfront.dll", CallingConvention = CallingConvention.Cdecl)]
    	private static extern void DBL_ConnectServer( string server_name, string net_type );	
    
    	[DllImport("cfront.dll", CallingConvention = CallingConvention.Cdecl)]
    	private static extern void DBL_DisconnectServer();
    
    	[DllImport("cfront.dll", CallingConvention = CallingConvention.Cdecl)]
    	private static extern void  DBL_ConnectServerAndOpenDatabase( string	NDBCDriverName
    								    , string	ServerName
    								    , string	NetType
    								    , string	DatabaseName
    								    , int	CacheSize
    								    , int	UseCommitCache
    								    , int	UseNTAuthentication
    								    , string	UserID
    								    , string	PassWord );
    
    	[DllImport("cfront.dll", CallingConvention = CallingConvention.Cdecl)]
    	private static extern int DBL_NextTable(int TableNo);
    
    	[DllImport("cfront.dll", CallingConvention = CallingConvention.Cdecl)]
    	private static extern int DBL_OpenTable(ref int hTablePtr, int TableNo );
    
    	[DllImport("cfront.dll", CallingConvention = CallingConvention.Cdecl)]
    	private static extern void DBL_CloseTable( int hTable );
    
    	[DllImport("cfront.dll", CallingConvention = CallingConvention.Cdecl)]
    	private static extern string DBL_TableName(int hTable);
    	
    	public static void Main(string[] args)
    	{
    		Console.WriteLine("Testing C/Front");
    		DBL_Init();
    		Console.WriteLine( "Version {0}", DBL_GetVersion() );		
    
    		DBL_ConnectServerAndOpenDatabase( "NDBCN"
    						, "192.168.0.10"
    						, "TCP"
    						, ""
    						, 10000
    						, 1
    						, 0
    						, "testuser"
    						, "abc123" );
    
    
    		int table_no = DBL_NextTable( 0 );
    		while((0 < table_no) && (table_no < 10))
    		{
    			int htable;
    			if( 0 != DBL_OpenTable( ref htable, table_no ) )
    			{
    				string name = DBL_TableName( htable );
    				Console.WriteLine( "Table {0}: {1}", table_no, name );							
    				DBL_CloseTable( htable );
    			}
    			else
    			{
    				Console.WriteLine( "Failed to Open Table {0}", table_no );
    			}
    		
    			table_no = DBL_NextTable( table_no );			
    		}
    
    		DBL_DisconnectServer();
    		DBL_Exit();	
    	}
    }
    
  • MrDeeMrDee Member Posts: 48
    Sorry - I am no C# programmer - I have tried this code in VS 2003 with the follwing results (BTW I also included the CFRONT.dll in my references Just in case)

    it is complaining at this line

    if( 0 != DBL_OpenTable( ref htable, table_no ) )

    with the following error

    C:\My Documents\Visual Studio Projects\NavisionTest\NavisionTest\MainClass.cs(72): Use of unassigned local variable 'htable'

    Any ideas?
  • scusackscusack Member Posts: 6
    Thanks for giving it a whirl, the line above that reads;
    int htable;

    should read
    int htable = 0;

    sorry for the typo
  • MrDeeMrDee Member Posts: 48
    :D It compiles...
    when I run it as a console app it compalins about CFRONT.dll.... I will look at it as time allows.
    In the meantime have you considered http://msdn.microsoft.com/vstudio/tryit/
    it provides an online (free) version of VS.net. for 3 hours (further blocks of time can be requested) 8)
  • athomaathoma Member Posts: 5
    Hi,

    change your code from
    [DllImport( "cfront.dll", CallingConvention = CallingConvention.Cdecl)]
    	private static extern Int32 DBL_Init();
    

    to
    [DllImport( "cfront.dll", CallingConvention = CallingConvention.Cdecl)]
    	private static extern bool DBL_Init();
    

    than your example works
    public static void Main(string[] args)
    {
    Console.WriteLine("Testing C/Front");
    bool bOk = DBL_Init();
    DBL_ConnectServer( "192.168.0.10", "TCP" );
    Console.WriteLine( "Version {0}", DBL_GetVersion() );
    DBL_Exit();
    }

    For converting from oem to ansi you can use nav functions
    [DllImport("cfront.dll",  SetLastError = true, CallingConvention = CallingConvention.Cdecl) ]
    		private static extern void DBL_Ansi2OemBuff ([In,Out] char[] Src, [In,Out] char[] Dst,int DstSize);
    		[DllImport("cfront.dll",  SetLastError = true, CallingConvention = CallingConvention.Cdecl) ]
    		private static extern void DBL_Oem2AnsiBuff ([In,Out] byte[] Src, [In,Out] byte[] Dst,int DstSize);
    

    Regards, Arek.

    P.S. Sorry for my bad english :)
  • scusackscusack Member Posts: 6
    Thanks Arek,

    I made the change but I still get "Internal Error 182 in Module 1", did the second example work for you?

    Are you using VS.NET or the SDK? I am using the SDK on Win2K and I am wondering if it forgot to installed some necessary dll.

    I will try your change again on a WinXP machine and see if that makes a difference, I am also going to try and get a demo of VS.NET and try that, if that works then I'll get work to shell out money for it. Until I can prove that it works I am facing an uphill battle.

    At least I know it works somewhere, which is great.

    Maybe we should all start collaborating on a C# module that wraps up C/Front, anybody interested?

    Thanks again, Simon.
  • athomaathoma Member Posts: 5
    I have VS.Net (WinXP). The example works with cfront.dll version 3.60/3.70.
    Don't forget copy cfront.dll into your debug/release folder.
    I work on wrapper class for navision. That works fine, but i have
    problems with handling errors and messages (see my post about DBL_SetMessageShowHandler ())

    regards, Arek
Sign In or Register to comment.