Port driver communication witout copy of binaries
Romain Lenglet
rlenglet@REDACTED
Wed Mar 29 08:55:51 CEST 2006
Valentin Micic wrote:
> Is there any reason for not using:
>
> erlang:port_call( Port, Cmd, DATA )
>
> which results in call to linked-in driver's:
>
> int edk_call( ErlDrvData handle, unsigned int cmd, char * buf,
> int len, char **rbuf, int rlen, unsigned int * flags )
>
> Argument DATA specified in erlang's port_call is passed by
> reference. The driver may return data in rbuf. Should there be
> more memory required that specified by rlen, such memory may
> be allocated, using driver_alloc... no need to free rbuf, as
> it points to automatic variable.
The problem is that I don't have only one binary to pass as an
argument. I need to pass a large binary AND other data along
(atoms, integers...), because those must be manipulated on the C
side. If I used port_call/3, I would have to build a binary to
pass as DATA on the Erlang side, which would imply copying the
large binary to create the DATA. I want to avoid that:
...
LargeBinaryToNotCopy = <<.....>>,
Data = <<Byte1, Byte2, LargeBinaryToNotCopy/binary, Byte3>>,
erlang:port_call(Port, Cmd, Data),
...
The IO-list-related primitives seem better, as pointed out by
Raimo Niskanen, since they do not require to copy the binary:
...
LargeBinaryToNotCopy = <<.....>>,
Data = [Byte1, Byte2, LargeBinaryToNotCopy, Byte3],
erlang:port_command(Port, Data),
...
And I have the same problem for return, but IO-list primitives
are a solution to my problem.
>
> V.
>
> PS
> I've been using this approach for integration with some ss7
> adapter... to cut the story short, it's working just fine.
> Documentation is indicating that this is the fastest way to
> interact with driver.
--
Romain LENGLET
More information about the erlang-questions
mailing list