Paste number 51529: FFI problem

Index of paste annotations: 4 | 3 | 2 | 1

Paste number 51529: FFI problem
Pasted by: matthewf
When:1 year, 7 months ago
Share:Tweet this! | http://paste.lisp.org/+13RD
Channel:#squeak
Paste contents:
Raw Source | XML | Display As
=============== What I want to wrap: ===================

///////////////////////////////////////////////////////////////////////////////
//	MPUSBWrite :
//
//  handle  - Identifies the endpoint pipe to be written to. The pipe handle
//            must have been created with MP_WRITE access attribute.
//
//  pData   - Points to the buffer containing the data to be written to the pipe.
//
//  dwLen   - Specifies the number of bytes to write to the pipe.
//
//  pLength - Points to the number of bytes written by this function call.
//            MPUSBWrite sets this value to zero before doing any work or
//            error checking.
//
//  dwMilliseconds
//          - Specifies the time-out interval, in milliseconds. The function
//            returns if the interval elapses, even if the operation is
//            incomplete. If dwMilliseconds is zero, the function tests the
//            data pipe and returns immediately. If dwMilliseconds is INFINITE,
//            the function's time-out interval never elapses.
//
//	Note that "input" and "output" refer to the parameter designations in calls
//	to this function, which are the opposite of common sense from the
//	perspective of an application making the calls.
//
DWORD MPUSBWrite(HANDLE handle,         // Input
                 PVOID pData,           // Input
                 DWORD dwLen,           // Input
                 PDWORD pLength,        // Output
                 DWORD dwMilliseconds)  // Input
{ ... }

================ How I wrapped it: ==================

apiUsbWrite: handle data: pData inputLen: dwLen outputLen: pLength milliseconds: dwMilliseconds
	<apicall: long '_MPUSBWrite' (long void* long long* long) module: 'mpusbapi.dll'>
	^self externalCallFailed

=================== How I am Calling it: ======================

write: aByteArray delay: aDelay
	
	| bytesWritten |
	bytesWritten := 0.
	self class
		apiUsbWrite: writePipe
		data: aByteArray
		inputLen: aByteArray size
		outputLen: bytesWritten
		milliseconds: aDelay.
	 ^ bytesWritten
		

Annotations for this paste:

Annotation number 4: what I found that works
Pasted by: matthewf
When:1 year, 7 months ago
Share:Tweet this! | http://paste.lisp.org/+13RD#4
Paste contents:
Raw Source | Display As
write: aByteArray timeout: aDelay
	
	| bytesWrittenHandle status |
	bytesWrittenHandle := ByteArray new: ExternalType long byteSize.
	status := self apiUsbWriteTo: writePipe
		buffer: (ExternalData fromHandle: aByteArray type: ExternalType void)
		bytesToWrite: aByteArray size
		bytesWritten: (ExternalData fromHandle: bytesWrittenHandle type: ExternalType long)
		timeout: aDelay.
	status = 1 ifFalse: [self error: 'Failed reading from device'].
	^ bytesWrittenHandle unsignedLongAt: 1
		

Annotation number 3: The right way to call it
Pasted by: Myself
When:1 year, 7 months ago
Share:Tweet this! | http://paste.lisp.org/+13RD#3
Paste contents:
Raw Source | Display As
=================== The Right Way To Call It: ======================

write: aByteArray delay: aDelay
        
        | bytesWritten |
        bytesWritten := WordArray with: 0.
        self class
                apiUsbWrite: writePipe
                data: aByteArray
                inputLen: aByteArray size
                outputLen: bytesWritten
                milliseconds: aDelay.
         ^bytesWritten at: 1

Annotation number 2: My wrapper suggestion
Pasted by: kencausey
When:1 year, 7 months ago
Share:Tweet this! | http://paste.lisp.org/+13RD#2
Paste contents:
Raw Source | Display As
I'm suggesting you write something like (I'm sure this is not quite right)

DWORD MyMPUSBWrite(HANDLE handle,         // Input
                   PVOID pData,           // Input
                   DWORD dwLen,           // Input
                   DWORD dwMilliseconds)  // Input

{
   DWORD returnVal;
   PDWORD pLength = (PDWORD)malloc(sizeof pLength);
   returnVal = MPUSBWrite(handle, pData, dwLen, dwMilliseconds);
   return *pLength;
}

Annotation number 1: What I tried previously
Pasted by: matthewf
When:1 year, 7 months ago
Share:Tweet this! | http://paste.lisp.org/+13RD#1
Paste contents:
Raw Source | Display As
I tried calling it like this before:

write: aByteArray delay: aDelay
	
	| outputLen |
	outputLen := ExternalData 
		fromHandle: (ExternalAddress gcallocate: 4)
		type: ExternalType long asPointerType.
	self class
		apiUsbWrite: writePipe
		data: aByteArray
		inputLen: aByteArray size
		outputLen: outputLen
		milliseconds: aDelay.
	 ^ outputLen
		

Colorize as:
Show Line Numbers
Index of paste annotations: 4 | 3 | 2 | 1

Lisppaste pastes can be made by anyone at any time. Imagine a fearsomely comprehensive disclaimer of liability. Now fear, comprehensively.