Problem: DLL unter BMax (spez. MS Speech API)- gelöst
Übersicht

Sokrates696Betreff: Problem: DLL unter BMax (spez. MS Speech API)- gelöst |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
*************************************************************************************
UPDATE : "Hab den Vorschlag von ChristianK" (- Vielen Dank -) Code aktualisiert ************************************************************************************* Holla, bastel seit einiger Zeit daran herum, diese SAPIDLL.dll (*1*) unter Blitzmax einzubinden und natürlich zum laufen zu bringen ![]() Laut der Webseite(*1*) ist die DLL als " 4. The SAPIDLL API SDK. All API is STDCALL " "compiliert", insofern dürfte dies den Vorrausetzungen entsprechen für die DLL-Einbindung unter Blitzmax. (so weit ich das dem englisch und deutschen Forum entnehmen konnte) Hab mal meinen bisherige Code angefügt. Die ist jetzt ein Version die scheinbar läuft - zumindest was die Existenz der Funktion und dem Laden der Dll angeht. Ich hatte, aber auch schon andere Varianten programmiert , die die üblich Memory Violation und nicht reference- Meldungen hervorbrachten...(Extern als Module einbinden...) Unter Purebasic (*2*) existiert ( - mit der gleichen DLL(?- nicht ganz sicher!)) ein Sourcecode der einwandfrei funktioniert. Unter Blitz3d (*3*) gibt es unter "So to Speak" ein DLL und Source, mit dieser Variante hab ich angefang eine Portierung hinzubekommen... Ich habe es mit beiden DLL's versucht, aber anscheinend produziere ich da nur Müll.. (Auf "Spam-Source" hab jetzt mal verzichtet ![]() In der Hoffnung, daß mir einer der Gurus aus diesem Forum ein Tip geben könnte, wie ich jetzt dieses Ding zum laufen bringen kann bzw. wie es jetzt weitergeht. Vielen Dank im Voraus Ansonst sind die Quellen vielleicht interessant ![]() Quellen: ----------- (*1*) http://wtwsoft.narod.ru/SAPIDLL/sapidlle.htm (*2*) http://www.purebasic.fr/german...6ff3bd9fa2 (*3*) http://www.sergiomarcello.com/ Code: [AUSKLAPPEN] Strict Import pub.win32 'DebugStop() ' ********** Variablen Def: Local DllName:String, DllHandle:Int '********** DLL-Def und Laden DllName = "SAPIDLL.dll" DllHandle = LoadLibraryA(DllName) ' ********** Testen ob's geladen wird If DllHandle = 0 Print "Dll konnte nicht geladen werden" End EndIf Global jpCreateSpeech() "Win32" = GetProcAddress(DllHandle,"CreateSpeech") Global jpGetEngineInfo(EngineName$z) "Win32" = GetProcAddress(DllHandle,"GetEngineInfo") Global jpGetEngines (EngineName$z) "Win32" = GetProcAddress(DllHandle,"GetEngines") Global jpSelectEngine (Number: Int) "Win32" = GetProcAddress(DllHandle,"SelectEngine") Global jpPSpeak (Text: String) "Win32" = GetProcAddress(DllHandle,"PSpeak") ' ************ Schaue ob Funktion vorhanden ist : Function FunctionExists(func:Byte Ptr) If func <> Null Return True EndIf Return False End Function If FunctionExists(jpCreateSpeech) Print "Funktion CreateSpeech existiert" Else Print "Funktion CreateSpeech konnte nicht aufgerufen werden" EndIf If FunctionExists(jpSelectEngine) Print "Funktion jpSelectEngine existiert" Else Print "Funktion jpSelectEngine konnte nicht aufgerufen werden" EndIf If FunctionExists(jpPSpeak) Print "Funktion jpPSpeak existiert" Else Print "Funktion jpjpPSpeak konnte nicht aufgerufen werden" EndIf '********** Hauptprogramm Print "TEST 1 START" If jpCreateSpeech() = 0 Print "CreateSpeech hat funktioniert " EndIf Rem ************************************************************************************ Aufrufe aus dem Delphi - Sample - Schnittstellen : siehe Webseite *1* Function CreateSpeech:HResult;stdcall;external 'SAPIDLL.DLL' name 'CreateSpeech'; procedure DestroySpeech;stdcall;external 'SAPIDLL.DLL'; procedure Speak( Text : String);stdcall;external 'SAPIDLL.DLL'; procedure SelectEngine(EngineName: String);stdcall;external 'SAPIDLL.DLL' name 'SelectEngine'; Function GetEngineInfo(EngineName: String; Var Info: TEngineInfo):Byte;stdcall;external 'SAPIDLL.DLL'; Function GetEngines:TStrings;stdcall;external 'SAPIDLL.DLL' name 'GetEngines'; Function GetEnginesCount:word;stdcall;external 'SAPIDLL.DLL'; Function GetPitch: Word;stdcall;external 'SAPIDLL.DLL'; Function GetSpeed: dword;stdcall;external 'SAPIDLL.DLL'; Function GetVolume: dword;stdcall;external 'SAPIDLL.DLL'; procedure SetPitch(Const Value: Word);stdcall;external 'SAPIDLL.DLL'; procedure SetSpeed(Const Value: dword);stdcall;external 'SAPIDLL.DLL'; procedure SetVolume(Const Value: dword);stdcall;external 'SAPIDLL.DLL'; Function GetMaxPitch: Word;stdcall;external 'SAPIDLL.DLL'; Function GetMaxSpeed: dword;stdcall;external 'SAPIDLL.DLL'; Function GetMaxVolume: dword;stdcall;external 'SAPIDLL.DLL'; Function GetMinPitch: Word;stdcall;external 'SAPIDLL.DLL'; Function GetMinSpeed: dword;stdcall;external 'SAPIDLL.DLL'; Function GetMinVolume: dword;stdcall;external 'SAPIDLL.DLL'; Procedure Pause;stdcall;external 'SAPIDLL.DLL'; Procedure Resume;stdcall;external 'SAPIDLL.DLL'; Procedure Stop;stdcall;external 'SAPIDLL.DLL'; // procedure PSpeak( Text: LPCTSTR );stdcall;external 'SAPIDLL.DLL'; procedure PSelectEngine(EngineName: LPCTSTR);stdcall;external 'SAPIDLL.DLL'; procedure PSelectEngineNumber(EngineNumber: word);stdcall;external 'SAPIDLL.DLL'; Function PGetEngines( number : word):LPCTSTR;stdcall;external 'SAPIDLL.DLL'; procedure RegistOnStart(CallbackAddr: TSpeechEvent);stdcall;external 'SAPIDLL.DLL'; procedure RegistOnPause(CallbackAddr: TSpeechEvent);stdcall;external 'SAPIDLL.DLL'; procedure RegistOnResume(CallbackAddr: TSpeechEvent);stdcall;external 'SAPIDLL.DLL'; procedure RegistOnStop(CallbackAddr: TSpeechEvent);stdcall;external 'SAPIDLL.DLL'; procedure RegistOnUserStart(CallbackAddr: TSpeechEvent);stdcall;external 'SAPIDLL.DLL'; procedure RegistOnUserStop(CallbackAddr: TSpeechEvent);stdcall;external 'SAPIDLL.DLL'; procedure RegistOnPosition(CallbackAddr: TPositionEvent);stdcall;external 'SAPIDLL.DLL'; procedure RegistOnSpeed(CallbackAddr: TPositionEvent);stdcall;external 'SAPIDLL.DLL'; procedure RegistOnVolume(CallbackAddr: TPositionEvent);stdcall;external 'SAPIDLL.DLL'; procedure RegistOnPitch(CallbackAddr: TPositionEvent);stdcall;external 'SAPIDLL.DLL'; procedure RegistOnSelectEngine(CallbackAddr: TEngineEvent);stdcall;external 'SAPIDLL.DLL'; procedure RegistOnStatusChange(CallbackAddr: TSpeechEvent);stdcall;external 'SAPIDLL.DLL'; procedure RegistOnError(CallbackAddr: TErrorEvent);stdcall;external 'SAPIDLL.DLL'; ' Andere Programmm zur DLL-einbindung Strict Framework brl.blitz Global Variable Local Kernel32 = LoadLibraryW ( "Kernel32.dll" ) Local GetModuleHandleExW ( Flags , Name:Byte Ptr , ModHandle Ptr ) "Win32" = GetProcAddress ( Kernel32 , "GetModuleHandleExW" ) Local ModHandle If GetModuleHandleExW ( 6 , Varptr Variable , Varptr ModHandle ) WriteStdout "The memory used for this variable is located in the following module: " + ModHandle + "~n" EndIf FreeLibrary Kernel32 Extern "Win32" Function LoadLibraryW ( Name$w ) Function GetProcAddress:Byte Ptr ( Library , Name$z ) Function FreeLibrary ( Library ) EndExtern End Rem |
||
- Zuletzt bearbeitet von Sokrates696 am Do, Jul 31, 2008 10:00, insgesamt 4-mal bearbeitet
ChristianK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ich hab mir deinen Code mal angeschaut und mir sind ein paar Dinge aufgefallen:
Function Pointer solltest du immer global deklarieren, sonst kannst du sie nicht innerhalb anderer Funktionen verwenden. In der Funktion FunctionExists machst du einen Int aus Byte Ptr. Vergleiche da besser den Zeiger mit Null. Beim Laden von jpSelectEngine musst du das "@4" hinter dem Funktionsnamen weglassen. |
||
AdvanceLcd
Intel Core 2 Duo 3.2 GHz, 4 GB RAM, GeForce 8800 GTX | MacBook Pro 15,4″ Intel Core 2 Duo 2.4 GHz, 2 GB RAM, GeForce 8600M GT |
Peak7810 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
da hab ich auch gleichmal eine frage.
für inline c++, wie muss man so ein stück code komplett für den Befehl Code: [AUSKLAPPEN] FreeLibraryAndExitThread aussehen?
brauch das dringend. |
||
![]() |
BtbN |
![]() Antworten mit Zitat ![]() |
---|---|---|
Es gibt in Bmax kein inline-C++ | ||
Peak7810 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
aber wenns gehen würde, ich muss so ein verdammtes fenster schliessen, was geöffnet wurde.
ist ein dx render fenster. wie müsste der c++ code aussehen, wenns inline geben würde? need help |
||
Sokrates696Betreff: Jetzt mal mit der SAPIDLL von Purebasic |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Holla,
so hab mich mal mit dem Purebasic-Variante beschäftigt (s.o.) " Unhandled Exception: Attempt to call uninitalized function pointer. " End of the Road ? Also ist es nicht möglich von Blitzmax auf eine DLL zuzugreifen. Ich weiss dass es offizielle sowieso nicht vorgesehen ist, aber .... Code: [AUSKLAPPEN] Strict Global ThisDLL = LoadLibraryA("SAPIDLL.dll") 'Note that you do not add the .DLL to the end of the library name If ThisDLL=0 Then Print "Can't load DLL" End; Global PCreateSpeech: Int (S2:Int) "win32" = GetProcAddress(ThisDLL, "CreateSpeech") Global PSelectEngineNumber:Byte Ptr (S1: Byte Ptr ) "win32" = GetProcAddress(ThisDLL, "PSelectEngineNumber@4") Global PSpeak:String (Str:String ) "win32" = GetProcAddress(ThisDLL, "PSelectEngineNumber@4") Local bpString1:String Local bpResult:String Local sString1:String Local sResult:String Local DD: Byte Ptr Local Zahl:String Zahl ="1" PCreateSpeech(1) DD = Zahl.ToCString() PSelectEngineNumber(DD) bpResult = Pspeak("Hallo") |
||
ChristianK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Wie gesagt, du musst das @4 weg lassen. ![]() Außerdem lädst du sowohl für PSelectEngineNumber, als auch für PSpeak die gleiche Funktion aus der DLL, nämlich PSelectEngineNumber. Für die zweite sollte es wohl PSpeak sein? Und statt dem Parameter str:String solltest du str$z angeben, denn BlitzMax hat seine eigenen Unicode-Strings und ich nehme mal an, dass die DLL C-Strings erwartet. |
||
AdvanceLcd
Intel Core 2 Duo 3.2 GHz, 4 GB RAM, GeForce 8800 GTX | MacBook Pro 15,4″ Intel Core 2 Duo 2.4 GHz, 2 GB RAM, GeForce 8600M GT |
Sokrates696 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
ChristianK hat Folgendes geschrieben: Wie gesagt, du musst das @4 weg lassen.
![]() Außerdem lädst du sowohl für PSelectEngineNumber, als auch für PSpeak die gleiche Funktion aus der DLL, nämlich PSelectEngineNumber. Für die zweite sollte es wohl PSpeak sein? - ![]() Zitat: Und statt dem Parameter str:String solltest du str$z angeben, denn BlitzMax hat seine eigenen Unicode-Strings und ich nehme mal an, dass die DLL C-Strings erwartet. Oh ! Sehr interessant - ich hatte dieses Zeichen zwar schon mal gesehen, aber keine Erklärung dazu gefunden..... Vielen Dank |
||
Sokrates696Betreff: Die Lösung mit Purebasic funzt :-) |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Holla,
nach dem sich wahrscheinlich - vermutlich- , daß halbe Forum totgelacht hat über mein Problem hab ich es dann doch endlich geschafft ![]() Diese Version läuft mit der Purebasic "SAPIDLL.dll" (s.o) . Vielen Dank nochmal an ChristianK. und all die anderen im Forum . Der letzte Lösungshinweis befandt sich im englischen Forum. Code: [AUSKLAPPEN] Strict Global ThisDLL = LoadLibraryA("SAPIDLL.dll") If ThisDLL=0 Then Print "Can't load DLL" End; Global PCreateSpeech: Int (S2:Int) "win32" = GetProcAddress(ThisDLL, "CreateSpeech") Global PSelectEngineNumber:Byte (S1: Byte ) "win32" = GetProcAddress(ThisDLL, "PSelectEngineNumber") Global PSpeak(str$z) "win32" = GetProcAddress(ThisDLL, "PSpeak") Local mystr:String="the really cool test string" Local strptr:Byte Ptr=mystr.ToCString() Local bpResult:String PCreateSpeech(1) PSelectEngineNumber(1) bpResult = Pspeak(mystr) WaitKey |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group