Hi all!
(It looks like my previous message was not properly delivered. Here is another try.) Can anybody help me with FFI? I'm trying to use LAME Mp3 Encoder DLL 3.96.1 (lame_enc.dll), but Squeak always crashes. Here is part of header file of DLL (whole header file, BladeMP3EncDLL.h, is attached): === Start of BladeMP3EncDLL.h ===================================== #define ATTRIBUTE_PACKED #pragma pack(push) #pragma pack(1) typedef struct { DWORD dwConfig; // BE_CONFIG_XXXXX // Currently only BE_CONFIG_MP3 is supported union { struct { DWORD dwSampleRate; // 48000, 44100 and 32000 allowed BYTE byMode; // BE_MP3_MODE_STEREO, BE_MP3_MODE_DUALCHANNEL, BE_MP3_MODE_MONO WORD wBitrate; // 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256 and 320 allowed BOOL bPrivate; BOOL bCRC; BOOL bCopyright; BOOL bOriginal; } mp3; // BE_CONFIG_MP3 struct { // STRUCTURE INFORMATION DWORD dwStructVersion; DWORD dwStructSize; // BASIC ENCODER SETTINGS DWORD dwSampleRate; // SAMPLERATE OF INPUT FILE DWORD dwReSampleRate; // DOWNSAMPLERATE, 0=ENCODER DECIDES LONG nMode; // BE_MP3_MODE_STEREO, BE_MP3_MODE_DUALCHANNEL, BE_MP3_MODE_MONO DWORD dwBitrate; // CBR bitrate, VBR min bitrate DWORD dwMaxBitrate; // CBR ignored, VBR Max bitrate LONG nPreset; // Quality preset, use one of the settings of the LAME_QUALITY_PRESET enum DWORD dwMpegVersion; // FUTURE USE, MPEG-1 OR MPEG-2 DWORD dwPsyModel; // FUTURE USE, SET TO 0 DWORD dwEmphasis; // FUTURE USE, SET TO 0 // BIT STREAM SETTINGS BOOL bPrivate; // Set Private Bit (TRUE/FALSE) BOOL bCRC; // Insert CRC (TRUE/FALSE) BOOL bCopyright; // Set Copyright Bit (TRUE/FALSE) BOOL bOriginal; // Set Original Bit (TRUE/FALSE) // VBR STUFF BOOL bWriteVBRHeader; // WRITE XING VBR HEADER (TRUE/FALSE) BOOL bEnableVBR; // USE VBR ENCODING (TRUE/FALSE) INT nVBRQuality; // VBR QUALITY 0..9 DWORD dwVbrAbr_bps; // Use ABR in stead of nVBRQuality VBRMETHOD nVbrMethod; BOOL bNoRes; // Disable Bit resorvoir (TRUE/FALSE) // MISC SETTINGS BOOL bStrictIso; // Use strict ISO encoding rules (TRUE/FALSE) WORD nQuality; // Quality Setting, HIGH BYTE should be NOT LOW byte, otherwhise quality=5 // FUTURE USE, SET TO 0, align strucutre to 331 bytes BYTE btReserved[255-4*sizeof(DWORD) - sizeof( WORD )]; } LHV1; // LAME header version 1 struct { DWORD dwSampleRate; BYTE byMode; WORD wBitrate; BYTE byEncodingMethod; } aac; } format; } BE_CONFIG, *PBE_CONFIG ATTRIBUTE_PACKED; __declspec(dllexport) BE_ERR beInitStream(PBE_CONFIG pbeConfig, PDWORD dwSamples, PDWORD dwBufferSize, PHBE_STREAM phbeStream); #pragma pack(pop) === End of BladeMP3EncDLL.h ====================================== Here is what I wrote to correspond DLL header (part of fileout, whole fileout is attached as LameTest.st). Default values are from Example.cpp (also attached), which works correct: === Start of LameTest.st =========================================== ExternalStructure subclass: #BeConfig instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'LameTest'! !BeConfig methodsFor: 'initialization' stamp: 'epb 6/21/2006 20:36'! initialize super initialize. self dwConfig: 256 "BE_CONFIG_LAME"; format: BeConfigFormat new.! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! BeConfig class instanceVariableNames: ''! !BeConfig class methodsFor: 'as yet unclassified' stamp: 'epb 6/20/2006 21:46'! fields "self defineFields" ^#( (dwConfig 'long' "BE_CONFIG_XXXXX. BE_CONFIG_MP3 = 0, BE_CONFIG_LAME = 256") (format 'BeConfigFormat') ) ! ! ExternalStructure subclass: #BeConfigFormat instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'LameTest'! !BeConfigFormat methodsFor: 'initialization' stamp: 'epb 6/21/2006 20:38'! initialize super initialize. self lhv1: BeConfigLvh1 new.! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! BeConfigFormat class instanceVariableNames: ''! !BeConfigFormat class methodsFor: 'as yet unclassified' stamp: 'epb 6/20/2006 21:44'! fields "self defineFields" ^#( (lhv1 'BeConfigLvh1') ) ! ! ExternalStructure subclass: #BeConfigLvh1 instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'LameTest'! !BeConfigLvh1 methodsFor: 'initialization' stamp: 'epb 6/22/2006 14:37'! initialize super initialize. self dwStructVersion: 1; dwStructSize: 333; dwReSampleRate: 0; setBeMp3ModeJStereo; dwBitrate: 128 "sizeof(beConfig)"; setPresetR3Mix; setMpeg1; dwPsyModel: 0; dwEmphasis: 0; bOriginal: 1; bWriteVBRHeader: 1! ! !BeConfigLvh1 methodsFor: 'set parameters' stamp: 'epb 6/21/2006 20:53'! setBeMp3ModeJStereo self nMode: 1! ! !BeConfigLvh1 methodsFor: 'lame quality presets' stamp: 'epb 6/21/2006 20:57'! setPresetR3Mix self nPreset: 4! ! !BeConfigLvh1 methodsFor: 'mpeg version' stamp: 'epb 6/21/2006 21:03'! setMpeg1 self dwMpegVersion: 1! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! BeConfigLvh1 class instanceVariableNames: ''! !BeConfigLvh1 class methodsFor: 'as yet unclassified' stamp: 'epb 6/22/2006 14:36'! fields "self defineFields" ^#( "STRUCTURE INFORMATION" (dwStructVersion 'long') (dwStructSize 'long') "BASIC ENCODER SETTINGS" (dwSampleRate 'long' "SAMPLERATE OF INPUT FILE") (dwReSampleRate 'long' "DOWNSAMPLERATE, 0=ENCODER DECIDES") (nMode 'long' "BE_MP3_MODE_STEREO, BE_MP3_MODE_DUALCHANNEL, BE_MP3_MODE_MONO") (dwBitrate 'long' "CBR bitrate, VBR min bitrate") (dwMaxBitrate 'long' "CBR ignored, VBR Max bitrate") (nPreset 'long' "Quality preset, use one of the settings of the LAME_QUALITY_PRESET enum") (dwMpegVersion 'long' "FUTURE USE, MPEG-1 OR MPEG-2") (dwPsyModel 'long' "FUTURE USE, SET TO 0") (dwEmphasis 'long' "FUTURE USE, SET TO 0") "BIT STREAM SETTINGS" (bPrivate 'long' "Set Private Bit (TRUE/FALSE)") (bCRC 'long' "Insert CRC (TRUE/FALSE)") (bCopyright 'long' "Set Copyright Bit (TRUE/FALSE)") (bOriginal 'long' "Set Original Bit (TRUE/FALSE)") "VBR STUFF" (bWriteVBRHeader 'long' "WRITE XING VBR HEADER (TRUE/FALSE)") (bEnableVBR 'long' "USE VBR ENCODING (TRUE/FALSE)") (nVBRQuality 'long' "VBR QUALITY 0..9") (dwVbrAbrBps 'long' "Use ABR in stead of nVBRQuality") (nVbrMethod 'long' "VBR_METHOD_NONE = -1, VBR_METHOD_DEFAULT = 0, VBR_METHOD_OLD = 1, VBR_METHOD_NEW = 2, VBR_METHOD_MTRH = 3, VBR_METHOD_ABR = 4") (bNoRes 'long' "Disable Bit resorvoir (TRUE/FALSE)") "MISC SETTINGS" (bStrictIso 'long' "Use strict ISO encoding rules (TRUE/FALSE)") (nQuality 'long' "Quality Setting, HIGH BYTE should be NOT LOW byte, otherwhise quality=5") "FUTURE USE, SET TO 0, align strucutre to 331 bytes" (btReserved 'byte' 237 "[255-4*sizeof(DWORD) - sizeof( WORD )]") )! ! Object subclass: #LameEncoder instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'LameTest'! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! LameEncoder class instanceVariableNames: ''! !LameEncoder class methodsFor: 'api' stamp: 'epb 6/21/2006 21:50'! apiBeInitStreamBeConfig: beConfig dwSamples: dwSamples dwMp3Buffer: dwMp3Buffer hbeStream: hbeStream <apicall: ulong 'beInitStream' ( BeConfig* long* long* ulong* ) module: 'lame_enc.dll'> ^self externalCallFailed! ! !LameEncoder class methodsFor: 'unit-tests' stamp: 'epb 6/29/2006 15:54'! testInitStream | beConfig errCode dwSamples dwMp3Buffer hbeStream | beConfig := BeConfig new sampleRate: 44100; yourself. dwSamples := WordArray new: 0. dwMp3Buffer := WordArray new: 0. hbeStream := WordArray new: 0. errCode := LameEncoder apiBeInitStreamBeConfig: beConfig dwSamples: dwSamples dwMp3Buffer: dwMp3Buffer hbeStream: hbeStream. Transcript show: 'errCode: '; show: errCode; cr; show: 'dwSamples: '; show: dwSamples first; cr; show: 'dwMp3Buffer: '; show: dwMp3Buffer first; cr; show: 'hbeStream: '; show: hbeStream first; cr.! ! === End of LameTest.st =========================================== When I'm executing "LameEncoder testInitStream", Squeak crashes. Here is stack dump: === Start of stack dump =========================================== --------------------------------------------------------------------- Fri Jul 14 14:39:58 2006 Exception code: C0000005 Exception addr: 00427325 Access violation (read access) at 00000480 EAX:00000480 EBX:88AA1235 ECX:115381B8 EDX:00000481 ESI:00000000 EDI:00520580 EBP:00520580 ESP:0006FB74 EIP:00427325 EFL:00010282 FP Control: FFFF027F FP Status: FFFF4861 FP Tag: FFFFFFFF VM Version: Squeak 3.7.1 (release) from Sep 23 2004 Compiler: gcc 2.95.2 19991024 (release) Current byte code: 209 Primitive index: 70 Loaded plugins: lame_enc.dll SqueakFFIPrims 23 September 2004 (e) LargeIntegers v1.3 23 September 2004 (i) Matrix2x3Plugin 23 September 2004 (i) FloatArrayPlugin 23 September 2004 (i) B2DPlugin 23 September 2004 (i) BitBltPlugin 23 September 2004 (i) SecurityPlugin 23 September 2004 (i) FilePlugin 23 September 2004 (i) MiscPrimitivePlugin 23 September 2004 (i) Stack dump: === End of stack dump =========================================== I tried to call this DLL by many ways, but without success. The best I did is asking DLL about it's version (beVersion). Can anybody help? -- Eugene BladeMP3EncDLL.h (10K) Download Attachment LameTest.st (23K) Download Attachment Example.cpp (10K) Download Attachment |
On 16-Jul-06, at 11:27 PM, Eugene Beschastnov wrote:
> > > dwSamples := WordArray new: 0. > dwMp3Buffer := WordArray new: 0. > hbeStream := WordArray new: 0. > > errCode := LameEncoder apiBeInitStreamBeConfig: beConfig dwSamples: > dwSamples dwMp3Buffer: dwMp3Buffer hbeStream: hbeStream. I'd suspect that setting up these three variables which are going to be pointers to store integers into and asking for 0 bytes of storage to be allocated for each is going to be an issue when the DLL attempts to write 4 bytes into those memory locations. I'd suggest rather you use dwSamples := ByteArray new: 4. and the accessors such as signedLongAt:put: to access the data, also for the sound data is it big endian or little endian? Accessors exist to allow you choose endian where the choice might not be platform dependent. Also cross check what the DWORD/BOOL in the software really resolves too. -- ======================================================================== === John M. McIntosh <[hidden email]> Corporate Smalltalk Consulting Ltd. http://www.smalltalkconsulting.com ======================================================================== === |
Thanks a lot, John!
"ByteArray new: 4" produces "Could not coerce arguments" error, but when I'm using "WordArray new: 1" it's OK. Thank you again! -- Eugene |
Another question - what construction in Squeak corresponds to PSHORT
in C? I tried ByteArray - Squeak produces error 'Could not coerce arguments', I tried WordArray - Squeak VM crashes. -- Eugene |
Am 19.07.2006 um 12:33 schrieb Eugene Beschastnov:
> Another question - what construction in Squeak corresponds to > PSHORT in C? There is no type PSHORT in C. It probably is a typedef (could be a macro too) which you need to lookup in the headers. I'd guess it's a 'short*'. - Bert - |
I'm not very good in C, but as I understand - yes, it is typedef for
'short*', but it's standard typedef. Anyway, what kind of data should I use to call FFI function that expects 'short*'? To be more specific, C function is __declspec(dllexport) BE_ERR beEncodeChunk(HBE_STREAM hbeStream, DWORD nSamples, PSHORT pSamples, PBYTE pOutput, PDWORD pdwOutput); ======================================================== For this function I made this apicall construction: apiBeEncodeChunkHbeStream: hbeStream nSamples: nSamples pSamples: pSamples pOutput: pOutput pdwOutput: pdwOutput <apicall: ulong 'beEncodeChunk' ( ulong long short* byte* long* ) module: 'lame_enc.dll'> ^self externalCallFailed ======================================================== And I'm trying to call it in following way: pMp3Buffer := ByteArray new: dwMp3Buffer. samples := (SampledSound fromWaveFileNamed: 'Message.wav') asSampledSound samples asWordArray. startOfChunk := 1. mp3Output := ByteArray new: 0. [startOfChunk <= samples size] whileTrue: [endOfChunk := startOfChunk + dwSamples - 1 min: samples size. buf := samples copyFrom: startOfChunk to: endOfChunk. startOfChunk := endOfChunk + 1. pDwWrite := WordArray new: 1. errCode := self apiBeEncodeChunkHbeStream: hbeStream nSamples: buf size pSamples: buf pOutput: pMp3Buffer pdwOutput: pDwWrite. errCode ~= self beErrSuccessful ifTrue: [self apiBeCloseStreamHbeStream: hbeStream. Exception signal: 'beEncodeChunk() failed (' , errCode asString , ')']. mp3Output addAll: (pMp3Buffer copyFrom: 1 to: pDwWrite first)]. (FileStream fileNamed: 'Message.mp3') binary next: mp3Output size putAll: mp3Output startingAt: 1 hbeStream, dwSamples and dwMp3Buffer are got from FFI function 'beInitStream', which is called earlier and executed correctly. 2006/7/19, Bert Freudenberg <[hidden email]>: > Am 19.07.2006 um 12:33 schrieb Eugene Beschastnov: > > > Another question - what construction in Squeak corresponds to > > PSHORT in C? > > There is no type PSHORT in C. It probably is a typedef (could be a > macro too) which you need to lookup in the headers. > > I'd guess it's a 'short*'. > > - Bert - > > > -- Eugene |
Given your application field, SoundBuffer should be fine.
- Bert - Am 19.07.2006 um 13:40 schrieb Eugene Beschastnov: > I'm not very good in C, but as I understand - yes, it is typedef for > 'short*', but it's standard typedef. > > Anyway, what kind of data should I use to call FFI function that > expects 'short*'? > > To be more specific, C function is > __declspec(dllexport) BE_ERR beEncodeChunk(HBE_STREAM hbeStream, > DWORD nSamples, PSHORT pSamples, PBYTE pOutput, PDWORD pdwOutput); > ======================================================== > For this function I made this apicall construction: > apiBeEncodeChunkHbeStream: hbeStream nSamples: nSamples pSamples: > pSamples pOutput: pOutput pdwOutput: pdwOutput > <apicall: ulong 'beEncodeChunk' ( ulong long short* byte* long* ) > module: 'lame_enc.dll'> > ^self externalCallFailed > ======================================================== > And I'm trying to call it in following way: > pMp3Buffer := ByteArray new: dwMp3Buffer. > samples := (SampledSound fromWaveFileNamed: 'Message.wav') > asSampledSound > samples asWordArray. > startOfChunk := 1. > mp3Output := ByteArray new: 0. > [startOfChunk <= samples size] whileTrue: > [endOfChunk := startOfChunk + dwSamples - 1 min: samples size. > buf := samples copyFrom: startOfChunk to: endOfChunk. > startOfChunk := endOfChunk + 1. > pDwWrite := WordArray new: 1. > errCode := self > apiBeEncodeChunkHbeStream: hbeStream > nSamples: buf size > pSamples: buf > pOutput: pMp3Buffer > pdwOutput: pDwWrite. > errCode ~= self beErrSuccessful > ifTrue: > [self apiBeCloseStreamHbeStream: hbeStream. > Exception signal: 'beEncodeChunk() failed (' , errCode > asString , ')']. > mp3Output addAll: (pMp3Buffer copyFrom: 1 to: pDwWrite first)]. > (FileStream fileNamed: 'Message.mp3') binary > next: mp3Output size > putAll: mp3Output > startingAt: 1 > > hbeStream, dwSamples and dwMp3Buffer are got from FFI function > 'beInitStream', which is called earlier and executed correctly. > > 2006/7/19, Bert Freudenberg <[hidden email]>: >> Am 19.07.2006 um 12:33 schrieb Eugene Beschastnov: >> >> > Another question - what construction in Squeak corresponds to >> > PSHORT in C? >> >> There is no type PSHORT in C. It probably is a typedef (could be a >> macro too) which you need to lookup in the headers. >> >> I'd guess it's a 'short*'. >> >> - Bert - >> >> >> > > > -- > Eugene |
So
samples := (SampledSound fromWaveFileNamed: 'Message.wav') asSampledSound samples. 'some code skipped...' buf := samples copyFrom: startOfChunk to: endOfChunk. 'some more code skipped...' errCode := self apiBeEncodeChunkHbeStream: hbeStream nSamples: buf size pSamples: buf pOutput: pMp3Buffer pdwOutput: pDwWrite. should be OK? But I already tried this and VM crashed (just checked again). Here is stack dump, but I don't see any helpful in it: --------------------------------------------------------------------- Wed Jul 19 21:48:10 2006 Exception code: C0000005 Exception addr: 04AD26D8 Access violation (write access) at 11A0A000 EAX:00000000 EBX:04BA0048 ECX:00000010 EDX:000000D8 ESI:04B91B98 EDI:11A0A000 EBP:04BA7D6C ESP:000670B8 EIP:04AD26D8 EFL:00010206 FP Control: FFFF027F FP Status: FFFF4877 FP Tag: FFFFFFFF VM Version: Squeak 3.7.1 (release) from Sep 23 2004 Compiler: gcc 2.95.2 19991024 (release) Current byte code: 32 Primitive index: 120 Loaded plugins: SocketPlugin 23 September 2004 (i) lame_enc.dll SqueakFFIPrims 23 September 2004 (e) SoundPlugin 23 September 2004 (i) LargeIntegers v1.3 23 September 2004 (i) Matrix2x3Plugin 23 September 2004 (i) FloatArrayPlugin 23 September 2004 (i) B2DPlugin 23 September 2004 (i) BitBltPlugin 23 September 2004 (i) SecurityPlugin 23 September 2004 (i) FilePlugin 23 September 2004 (i) MiscPrimitivePlugin 23 September 2004 (i) Stack dump: 291203288 LameEncoder class>testEncode 291203176 UndefinedObject>DoIt 291200616 Compiler>evaluate:in:to:notifying:ifFail:logged: 291200708 [] in ParagraphEditor>evaluateSelection 291200432 BlockContext>on:do: 291200340 ParagraphEditor>evaluateSelection 291200248 ParagraphEditor>doIt 291200524 [] in ParagraphEditor>doIt: 291200156 Controller>terminateAndInitializeAround: 291200064 ParagraphEditor>doIt: 291199816 ParagraphEditor>dispatchOnCharacter:with: 291199724 TextMorphEditor>dispatchOnCharacter:with: 291199632 ParagraphEditor>readKeyboard 291199540 TextMorphEditor>readKeyboard 291199176 [] in TextMorph>keyStroke: 291199084 TextMorph>handleInteraction:fromEvent: 291198992 TextMorphForEditView>handleInteraction:fromEvent: 291198848 TextMorph>keyStroke: 291198756 TextMorphForEditView>keyStroke: 291198664 TextMorph>handleKeystroke: 291198296 KeyboardEvent>sentTo: 291198204 Morph>handleEvent: 291198112 Morph>handleFocusEvent: 291198388 [] in HandMorph>sendFocusEvent:to:clear: 291198480 [] in PasteUpMorph>becomeActiveDuring: 291198020 BlockContext>on:do: 291197928 PasteUpMorph>becomeActiveDuring: 291197704 HandMorph>sendFocusEvent:to:clear: 291197612 HandMorph>sendEvent:focus:clear: 291197520 HandMorph>sendKeyboardEvent: 291197428 HandMorph>handleEvent: 291197208 HandMorph>processEvents 291197300 [] in WorldState>doOneCycleNowFor: 291197116 SequenceableCollection>do: 291197024 WorldState>handsDo: 291196932 WorldState>doOneCycleNowFor: 291196840 WorldState>doOneCycleFor: 291196748 PasteUpMorph>doOneCycle 288143892 [] in Project class>spawnNewProcess 288144076 [] in BlockContext>newProcess 2006/7/19, Bert Freudenberg <[hidden email]>: > Given your application field, SoundBuffer should be fine. > > - Bert - -- Eugene |
I think it looks fine. But there's a lot that can go wrong when you
do FFI. You need to check and double-check everything actually does what you think it does. A C debugger might help, too. - Bert - Am 19.07.2006 um 17:06 schrieb Eugene Beschastnov: > So > samples := (SampledSound fromWaveFileNamed: 'Message.wav') > asSampledSound samples. > 'some code skipped...' > buf := samples copyFrom: startOfChunk to: endOfChunk. > 'some more code skipped...' > errCode := self > apiBeEncodeChunkHbeStream: hbeStream > nSamples: buf size > pSamples: buf > pOutput: pMp3Buffer > pdwOutput: pDwWrite. > > should be OK? But I already tried this and VM crashed (just checked > again). > > Here is stack dump, but I don't see any helpful in it: > --------------------------------------------------------------------- > Wed Jul 19 21:48:10 2006 > > Exception code: C0000005 > Exception addr: 04AD26D8 > Access violation (write access) at 11A0A000 > EAX:00000000 EBX:04BA0048 ECX:00000010 EDX:000000D8 > ESI:04B91B98 EDI:11A0A000 EBP:04BA7D6C ESP:000670B8 > EIP:04AD26D8 EFL:00010206 > FP Control: FFFF027F > FP Status: FFFF4877 > FP Tag: FFFFFFFF > VM Version: Squeak 3.7.1 (release) from Sep 23 2004 > Compiler: gcc 2.95.2 19991024 (release) > > Current byte code: 32 > Primitive index: 120 > > Loaded plugins: > SocketPlugin 23 September 2004 (i) > lame_enc.dll > SqueakFFIPrims 23 September 2004 (e) > SoundPlugin 23 September 2004 (i) > LargeIntegers v1.3 23 September 2004 (i) > Matrix2x3Plugin 23 September 2004 (i) > FloatArrayPlugin 23 September 2004 (i) > B2DPlugin 23 September 2004 (i) > BitBltPlugin 23 September 2004 (i) > SecurityPlugin 23 September 2004 (i) > FilePlugin 23 September 2004 (i) > MiscPrimitivePlugin 23 September 2004 (i) > > > Stack dump: > > 291203288 LameEncoder class>testEncode > 291203176 UndefinedObject>DoIt > 291200616 Compiler>evaluate:in:to:notifying:ifFail:logged: > 291200708 [] in ParagraphEditor>evaluateSelection > 291200432 BlockContext>on:do: > 291200340 ParagraphEditor>evaluateSelection > 291200248 ParagraphEditor>doIt > 291200524 [] in ParagraphEditor>doIt: > 291200156 Controller>terminateAndInitializeAround: > 291200064 ParagraphEditor>doIt: > 291199816 ParagraphEditor>dispatchOnCharacter:with: > 291199724 TextMorphEditor>dispatchOnCharacter:with: > 291199632 ParagraphEditor>readKeyboard > 291199540 TextMorphEditor>readKeyboard > 291199176 [] in TextMorph>keyStroke: > 291199084 TextMorph>handleInteraction:fromEvent: > 291198992 TextMorphForEditView>handleInteraction:fromEvent: > 291198848 TextMorph>keyStroke: > 291198756 TextMorphForEditView>keyStroke: > 291198664 TextMorph>handleKeystroke: > 291198296 KeyboardEvent>sentTo: > 291198204 Morph>handleEvent: > 291198112 Morph>handleFocusEvent: > 291198388 [] in HandMorph>sendFocusEvent:to:clear: > 291198480 [] in PasteUpMorph>becomeActiveDuring: > 291198020 BlockContext>on:do: > 291197928 PasteUpMorph>becomeActiveDuring: > 291197704 HandMorph>sendFocusEvent:to:clear: > 291197612 HandMorph>sendEvent:focus:clear: > 291197520 HandMorph>sendKeyboardEvent: > 291197428 HandMorph>handleEvent: > 291197208 HandMorph>processEvents > 291197300 [] in WorldState>doOneCycleNowFor: > 291197116 SequenceableCollection>do: > 291197024 WorldState>handsDo: > 291196932 WorldState>doOneCycleNowFor: > 291196840 WorldState>doOneCycleFor: > 291196748 PasteUpMorph>doOneCycle > 288143892 [] in Project class>spawnNewProcess > 288144076 [] in BlockContext>newProcess |
In reply to this post by Eugene Beschastnov
So how many bytes are being allocated here?
how many bytes do you expect to write into that location? Are these bytes, or words you're expecting? 1 word -> 4 bytes? On 19-Jul-06, at 4:40 AM, Eugene Beschastnov wrote: > And I'm trying to call it in following way: > pMp3Buffer := ByteArray new: dwMp3Buffer. Lastly I'll note that mp3Output addAll: (pMp3Buffer copyFrom: 1 to: pDwWrite first)]. could be expressed as this, since the copyFrom:to: makes a new object of the same class as the original, no need to stuff that new object into mp3Output. mp3Output := pMp3Buffer copyFrom: 1 to: pDwWrite first. regarding pDwWrite first Ah, likely you should do pDwWrite := ByteArray new: 4. then say pDwWrite signedLongAt: 1 if it's a signed long in platform endian you expect to find there, this is clearer than hoping the value you got stuff in there is an integer of some sort in the right endian format. -- ======================================================================== === John M. McIntosh <[hidden email]> Corporate Smalltalk Consulting Ltd. http://www.smalltalkconsulting.com ======================================================================== === |
In reply to this post by Bert Freudenberg-3
I digged a little into C-code and found that hbeStream is pointer to
some LAME data (some global flags are stored there). I suppose that root of problem is that this data is destroyed or moved between apicalls. Is there any way to avoid this? -- Eugene |
Is it possible that Squeak closes external library (in my case it is
DLL) after every external function call? If yes, is it possible to force it to not close external library (I'd prefer to close it manually when needed, but even staying it opened is good enough). -- Eugene |
Eugene Beschastnov wrote:
> Is it possible that Squeak closes external library (in my case it is > DLL) after every external function call? No. Cheers, - Andreas |
In reply to this post by Eugene Beschastnov
I retry sending since it failed... ---------- Message transmis ---------- Subject: Re: Help with FFI - another try Date: Vendredi 21 Juillet 2006 22:49 From: nicolas cellier <[hidden email]> To: The general-purpose Squeak developers list <[hidden email]> Le Vendredi 21 Juillet 2006 13:15, Eugene Beschastnov a écrit : > I digged a little into C-code and found that hbeStream is pointer to > some LAME data (some global flags are stored there). I suppose that > root of problem is that this data is destroyed or moved between > apicalls. Is there any way to avoid this? One solution is to allocate this data on external heap. (See ExternalAddress class>>allocate:) instead of using a ByteArray in Smalltalk memory. Of course, you'll have to free data yourself as in C. Maybe the trick explained at http://bugs.impara.de/view.php?id=3692 that should be in latest image can help... Nicolas ------------------------------------------------------- |
In reply to this post by Eugene Beschastnov
I retry sending because it failed...
---------- Message transmis ---------- Subject: Re: Help with FFI - another try Date: Vendredi 21 Juillet 2006 23:13 From: nicolas cellier <[hidden email]> To: Squeak-dev developers list general-purpose Squeak <[hidden email]> Le Vendredi 21 Juillet 2006 22:49, nicolas cellier a écrit : > Le Vendredi 21 Juillet 2006 13:15, Eugene Beschastnov a écrit : > > I digged a little into C-code and found that hbeStream is pointer to > > some LAME data (some global flags are stored there). I suppose that > > root of problem is that this data is destroyed or moved between > > apicalls. Is there any way to avoid this? > > One solution is to allocate this data on external heap. > (See ExternalAddress class>>allocate:) instead of using a ByteArray in > Smalltalk memory. > > Of course, you'll have to free data yourself as in C. > Maybe the trick explained at http://bugs.impara.de/view.php?id=3692 that > should be in latest image can help... > > Nicolas My last post was too short: i remember it is not that obvious to guess the right object which should be passed as FFI call argument. It is an ExternalData, a combination of an ExternalAddress and an ExternalType. And one more thing: don't expect ExternalAddress to survive across image snapshots. If you want to survive, you must transfer data into a ByteArray before saving the image, and transfer to a newly allocated ExternalAddress before next use... But maybe this is not a problem. in Smallapack-Collection, i have a class ExternalArray doing this kind of tirck: ExternalArray>>resetExternalData "Reset the ExternalData object used as FFI argument. This is cached in an inst-var instead of being recreated at each call. However, this must be reset whenever handle is changed" | cType | cType := self class type. data := cType isStructureType ifTrue: [ "Arrays of structure cannot carry type checking in FFI" ExternalData fromHandle: handle type: ExternalType void] ifFalse: [ "Atomic types" ExternalData fromHandle: handle type: cType] where handle is sometimes a ByteArray in Smalltalk memory, sometimes an ExternalAddress according to my needs. ExternalArray>>copyInCSpace "Answer a copy of self with data in C space" ^self shallowCopy postCopyInCSpace ExternalArray>>postCopyInCSpace "Copy the data into a new array" | newHandle bs | handle isNil ifFalse: [bs := self byteSize. newHandle := ExternalAddress gcallocate: bs. self memcpyDest: newHandle fromSource: handle nBytes: bs. self setHandle: newHandle] Maybe you have enough elements or you can browse more at squeak source http://www.squeaksource.com/@ZGaVjYGiHOshVjSM/LGmmIzpi Nicolas ------------------------------------------------------- |
In reply to this post by Andreas.Raab
Le Lundi 24 Juillet 2006 13:37, Andreas Raab a écrit :
> Eugene Beschastnov wrote: > > Is it possible that Squeak closes external library (in my case it is > > DLL) after every external function call? > > No. > > Cheers, > - Andreas If really wanted, you would have to hack the plugin... Is there any use of unloading a DLL? Nicolas |
Free forum by Nabble | Edit this page |