We help IT Professionals succeed at work.

acmDriverEnum problem

Madorsky
Madorsky asked
on
Medium Priority
479 Views
Last Modified: 2010-04-03
I'm trying to link msacm32.dll to my Delphi program.
Everything goes well until I try to call acmDriverEnum -
I receive different Error messages, sometimes Windows symply
hungs and so on. I think the problem is how to correctly
declare the Callback function and pass it's address to
acmDriverEnum. If somebody has a piece of working Delphi
code which calls acmDriverEnum - would you like to send it
here?
Thank you. Alex.
Comment
Watch Question

Commented:
As you haven't posted the failing source, it's kind of hard to tell what the problem is.

But, a common mistake is to forget the stdcall directive. Almost all callback functions should be declared using this.


E.g.

procedure ThisIsACallback(AParam, AnotherParam : DWORD); stdcall;
begin
end;


If this isn't the problem, leave me a comment along with some source code, and I'll have a look at it.


Regards,

Erik.

Author

Commented:
var
  acmGetVersion: function : DWORD;
  acmDriverEnum: function(fnCallback: Pointer; dwInstance,                           fdwEnum: DWORD) : DWORD ;


function RealCallback
         (
              hadid: DWORD;
              dwInstance, fdwSupport: DWORD
         ):Boolean; stdcall;
{I've tried also cdecl, pascal and so on - without success}
begin
     Result := True;
end;

procedure TForm1.Button1Click(Sender: TObject);
var lhDll, sfHandle: DWORD;
begin

     lhDll := LoadLibrary ('msacm32.dll');
     if lhDll < 32 then
     begin
          MessageDlg('No DLL', mtError, [mbOk], 0);
     end;

     @acmGetVersion := GetProcAddress(lhDll, 'acmGetVersion');
     if @acmGetVersion = nil then
     begin
          MessageDlg('No acmGetVersion', mtError, [mbOk], 0);
     end;

     @acmDriverEnum := GetProcAddress(lhDll, 'acmDriverEnum');
     if @acmDriverEnum = nil then
     begin
          MessageDlg('No acmDriverEnum', mtError, [mbOk], 0);
     end;

     Label1.Caption := IntToHex(acmGetVersion, 8);
{The result is $04000000 - looks good}

     acmDriverEnum(@RealCallBack, 0, 0);
{Here it hungs}
end;
{I've also tried to create the procedural type and variable of
that type, and pass that var to acmDriverEnum by reference -
result is the same.}

Commented:
var
  acmGetVersion: function : DWORD;
  acmDriverEnum: function(fnCallback: Pointer; dwInstance, fdwEnum: DWORD) : DWORD ;


Here's the error.

Append a stdcall to these lines.

  acmGetVersion: function : DWORD; stdcall;
  acmDriverEnum: function(fnCallback: Pointer; dwInstance, fdwEnum: DWORD) : DWORD ; stdcall;

acmGetVersion works regardless of calling convention, because it doesn't take any parameters, and return value is passed back the same way in all calling conventions. acmDriverEnum expects parameters to be passed using "stdcall", while your declaration passes parameters using the default "register"


Regards

Erik.

Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts
Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.