Jump to content
Sign in to follow this  
maalrron

need help for creation of a named pipe for a motion flight simulator chair!

Recommended Posts

hi,

i've been trying to create a pipe between arma 3 and a hand made software but i can't seem to make it work.

i want to export a stream of a few vector of the player, like direction, up and speed. that is to create a motion chair like a flight simulator.

i've seen that there's this:

handle = "pipes" callExtension "openPipe(pipe)";

http://community.bistudio.com/wiki/callExtension

but the example is kind of very light. i'd like to know how the extension pipes work and i haven't been able to find any documentation about it.

same with the "openPipe" function.

hope someone will be kind enough to help me.

cheers

---------- Post added at 00:12 ---------- Previous post was at 22:17 ----------

i guess i need to create my own extension with a c++ code that opens the created pipe and write in it.

am i right?

Share this post


Link to post
Share on other sites

CallExtension doesn't have any implemented functions, instead it calls code that you make on your own. The wiki is a bit misleading in the fact that the above code won't do anything unless you make a dynamic link library (dll) named "pipes" and that can parse the "openPipe(pipe)" string to something useful.

In order to utilized external commands, you need to code a dll, probably in an unmanaged C-type language (C, C++, etc). This task is very low-level, and one would require a lot of coding experience to create a dll from these types of strongly-typed languages.

So unfortunately this isn't something that you can do without first properly learning an unmanaged programming language like C or C++.

Reference the BIKI page on extensions for more information: http://community.bistudio.com/wiki/Extensions

Also if you want to get a feel for the type of code needed for these types of addons, you can check out my [outdated] Naught.Net addon, which utilizes dll extensions: https://github.com/dylanplecki/Naught.Net/tree/master/source/c/Naught.Net.dll/Naught.Net

Edited by Naught

Share this post


Link to post
Share on other sites

hi!

so here i come back for the update.

Naught was right (exept when he said "this isn't something that you can do without first properly learning an unmanaged programming language like C or C++." ;) ), the callExtension was indeed the right call.

as he says:

1/ create a separate application that will create and read a pipe.

2/ create an arma dll that opens said pipe and right datas in it (look at the tutorials in the 1rst link Naught posted).

3/ use callExtension to call this dll and feed it the data you wanna send.

4/ while loop the whole thing and you have a "real time" stream of data.

Now my main concern is about the multiplayer. since i'll need to call my script (the one with the callExtension in it), i'll need to create an addon. the thing is that i won't be able to play multiplayer without the right key.

- also, i've been looking for a way to assign a custom user control key to activate that script but couldn't make it work. i guess the name isn't the same in arma 3 that it was it arma 2. anybody?

here is the code for the dll for those who want. (C++)

// pipeExtension.cpp : Defines the exported functions for the DLL application.
#include "stdafx.h"
//

///// CLIENT PROGRAM /////

using namespace std;

extern "C"
{
__declspec(dllexport) void __stdcall RVExtension(char *output, int outputSize, const char *function);
};

void __stdcall RVExtension(char *output, int outputSize, const char *function)
{
// Open the named pipe
HANDLE pipe = CreateFile(
	L"\\\\.\\pipe\\arma",  // name of the pipe called in callExtension
	GENERIC_WRITE, // only need write access
	FILE_SHARE_READ | FILE_SHARE_WRITE,
	NULL,
	OPEN_EXISTING,
	FILE_ATTRIBUTE_NORMAL,
	NULL
	);

		// This call blocks until a client process reads all the data
DWORD numBytesWritten = 0;
BOOL result = WriteFile(
	pipe, // handle to our outbound pipe
	function, // data to send
	strlen(function)*sizeof(char), // length of data to send (bytes)
	&numBytesWritten, // will store actual amount of data sent
	NULL // not using overlapped IO
	);
CloseHandle(pipe);
}

and this is a code for creating the pipe.

#include <iostream>
#include <windows.h>

using namespace std;

int main(int argc, const char **argv)
{

wcout << "Creating an instance of a named pipe..." << endl;
// Create a pipe to send data

	HANDLE pipe = CreateNamedPipe(
	"\\\\.\\pipe\\arma", // name of the pipe
	PIPE_ACCESS_DUPLEX, // 2-ways pipe
	//PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, // send data as a byte stream
	PIPE_TYPE_BYTE,
	1, // only allow 1 instance of this pipe
	0, // no outbound buffer
	0, // no inbound buffer
	0, // use default wait time
	NULL // use default security attributes
	);
	//PIPE_TYPE_BYTE
if (pipe == NULL || pipe == INVALID_HANDLE_VALUE) {
	wcout << "Failed to create outbound pipe instance.";
	// look up error code here using GetLastError()
	system("pause");
	return 1;
}

wcout << "Waiting for a client to connect to the pipe..." << endl;

// This call blocks until a client process connects to the pipe
int count = 0;
BOOL result;
DWORD numBytesRead = 0;
char buffer[128];

result = ConnectNamedPipe(pipe, NULL);
if (!result) {
	wcout << "Failed to make connection on named pipe." << endl;
	// look up error code here using GetLastError()
	CloseHandle(pipe); // close the pipe
	system("pause");
	return 1;
}

wcout << "Reading data from pipe..." << endl;

// The read operation will block until there is data to read

	result = ReadFile(
		pipe,
		buffer, // the data from the pipe will be put here
		127 * sizeof(char), // number of bytes allocated
		&numBytesRead, // this will store number of bytes actually read
		NULL // not using overlapped IO
		);

	if (result) {
		buffer[numBytesRead / sizeof(char)] = '\0'; // null terminate the string
		wcout << "Number of bytes read: " << numBytesRead << endl;
		wcout << "Message: " << buffer << endl;

	}
	else {
		wcout << "Failed to read data from the pipe." << endl;
	}
	char *st;
// Close our pipe handle
CloseHandle(pipe);
if (buffer)
{
	st = buffer;
}
string str(buffer);
wcout << str.c_str() << endl;

system("pause");
return 0;
}

cheers!

Edited by maalrron

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×