Consume DLL C on VB6 or C#

Asked

Viewed 2,287 times

1

I have a DLL (gbasmsb_library.dll) provided by Farmácia Popular responsible for returning some functions for interaction with this environment.
I think it is a DLL written in C, I need to consume this DLL in VB6 OR C#.

In the Programmer’s guide programmer have the following information for using the DLL:
1:

Syntax:

const char* IdentificaEstacao();

Return value: A string containing the machine’s DNA.

2:

Syntax:

const char* PegaSolicitacao( 
const char* CNPJ, 
const char* CPF, 
const char* CRM, 
const char* UF_CRM, 
const char* DT_EMISSAO );

A string that will be used to validate the request by generating the machine.

In VB6 managed to consume the first function (1), while the second returns error:

49 Bad DLL Calling Convention

Code VB6:

Private Declare Function PegaSolicitacao Lib "c:\temp\gbasmsb_library.dll" (ByRef CNPJ As String, ByRef CPF As String, ByRef CRM As String, ByRef UF_CRM As String, ByRef DT_EMISSAO As String) As String
Private Declare Function IdentificaEstacao Lib "c:\temp\gbasmsb_library.dll" () As String
    Private Sub Form_Load()
      MsgBox (IdentificaEstacao) //1 - retorno OK    

      Dim CNPJ As String, CPF As String, CRM As String, UF_CRM As String, DT_EMISSAO As String

      Dim resp As String
      CNPJ = "98352942000133"
      CPF = "72794534491"
      CRM = "7347"
      UF_CRM = "AM"
      DT_EMISSAO = "01/01/1991"
      resp = PegaSolicitacao(CNPJ, CPF, CRM, UF_CRM, DT_EMISSAO) //2 - ERRO
    end sub

I already changed the function signature to byval, changed the parameter to array also unsuccessfully.

Code C# Unsuccessful in calling any FUNCTION.

[DllImport(@"c:\temp\gbasmsb_library.dll")]
private static extern string PegaSolicitacao(string cnpj, string cpf, string crm, string ufCrm, string dtEmissao);

[DllImport(@"c:\temp\gbasmsb_library.dll")]
private static extern string IdentificaEstacao();

private void button1_Click(object sender, EventArgs e)
{
    var cnpj = "98352942000133";
    var cpf = "72794534491";
    var crm = "7347";
    var ufCrm = "PI";
    var dtEmissao = "01/01/1991";
    //MessageBox.Show(PegaSolicitacao(ref cnpj, ref cnpj, ref cnpj, ref cnpj, ref cnpj));
    //ERRO
    MessageBox.Show(PegaSolicitacao(cnpj, cpf, crm, ufCrm, dtEmissao));
    //ERRO
    IdentificaEstacao();
}

1 answer

3


C/C++ libraries have call convention (the way the method is handled by the CPU, its stack, etc.), this implies otmization.

https://msdn.microsoft.com/en-us/library/k2b2ssfy.aspx

Anyway, your solution is here:

https://msdn.microsoft.com/en-us/library/aa232602%28v=vs.60%29.aspx

Make sure the arguments are correct and in the same order, as well as the function name, also specify the call convention directly in the attribute:

    // analise sua DLL, talvez não seja StdCall, pode ser Cdecl ou outras convenções
    [DllImport("Foo.dll", CallingConvention = CallingConvention.StdCall)]
    public static extern void FooMethod();

Perhaps some extra points are needed such as CharSet (Unicode or Ansi) and ExactSpelling=true

Another important point:

https://stackoverflow.com/questions/370079/pinvoke-for-c-function-that-returns-char

Strings (char* for string) -> Use System.Intptr since char* is a pointer, you will need to create the string after calling the method by copying by Marshal.

Signing of Duties

public class Gba
{

    //const char* IdentificaEstacao();
    [return: MarshalAsAttribute(UnmanagedType.AnsiBStr)]
    [DllImport("gba.dll", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
    public static extern string IdentificaEstacao();

    //const char* PegaSolicitacao( const char* CNPJ, const char* CPF, const char* CRM, const char* UF_CRM, const char* DT_EMISSAO );
    [return: MarshalAsAttribute(UnmanagedType.AnsiBStr)]
    [DllImport("gba.dll", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
    public static extern string PegaSolicitacao(string CNPJ, string CPF, string CRM, string UF_CRM, string DT_EMISSAO );

    //const char* PegaConfirmacao( const char* CNPJ, const char* NU_AUTORIZACAO, const char* NU_CUPOM_FISCAL );
    [return: MarshalAsAttribute(UnmanagedType.AnsiBStr)]
    [DllImport("gba.dll", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
    public static extern string PegaConfirmacao(string CNPJ, string NU_AUTORIZACAO, IntPtr NU_CUPOM_FISCAL );
}
  • Thanks for the reply @Leonardo-bosquett tried various settings but unsuccessfully. Foi feita uma tentativa de se carregar um programa com um formato incorreto. (Exceção de HRESULT: 0x8007000B)

  • 1

    I modified the answer, your exception is probably caused because you are creating a 64-bit executable

  • 1

    Really killed the puzzle was ANYCPU switched to x86 and it worked! I also made some changes to return the string value, follow the code to update your answer: [return: MarshalAs(UnmanagedType.AnsiBStr)]
public static extern string IdentificaEstacao(); Thank you @Leonard-bosquett.

  • 1

    The signature of the other functions receive string instead of IntPtr @Eonardo-bosquett

Browser other questions tagged

You are not signed in. Login or sign up in order to post.