Is there a compiler switch I'm not seeing that would allow me to omit the assembler keyword from assembler functions?
How I do it now, using example from FPC docs:
function geteipasebx : pointer;assembler;
asm
movl (%esp),%ebx
ret
end;
How I would like to do it:
function geteipasebx : pointer;
asm
movl (%esp),%ebx
ret
end;
Can this be done?
EDIT:
compiler source file PSUB.PAS line 170:
{ do we have an assembler block without the po_assembler?
we should allow this for Delphi compatibility (PFV) }
if (token=_ASM) and (m_delphi in current_settings.modeswitches) then
include(current_procinfo.procdef.procoptions,po_assembler);
{ Handle assembler block different }
if (po_assembler in current_procinfo.procdef.procoptions) then ...
I believe this part of the source code of free pascal means that this can only be done in {$MODE DELPHI}.
Yes this can be done. You have to set the compiler compatibility mode to DELPHI and to redefine the asm syntax to ATT, since the mode DELPHI will override it to INTEL.
more concretly, the program:
program Project1;
{$MODE DELPHI}
{$ASMMODE ATT}
function geteipasebx : pointer;
asm
movl (%esp),%ebx
ret
end;
var
p: pointer;
begin
p := geteipasebx;
end.
compiles and run fine.
Related
I want to have a Scilab function which is able to alter its input variables, For example in C I could have
void double(int* x){
*x *= 2;
return;
}
There are intppty, funptr, addinter, istk, sadr and stk in Scilab which seem to be relevant, however I can't find any working example. Scilab does have a pointer type (i.e. 128). I would appreciate if you could help me figure this out.
P.S.1. I have also mirrored this question here on Reddit.
P.S.2. Scilab also have intersci, SWIG, fort, external, call, API_Scilab/gateway which can interface C/C++ functions or Fortran subroutines. Unfortunately intersci has been deprecated and SWIG seems to be only for Linux with limited C++ compatibility.
P.S.3. scilab has function overloading which can do stuff with the functions defined by deff and a combination of %,<...>,_... syntax.
P.S.4. The way API_Scilab/gateway works, is basically you dvelop the code using functionalities provided bu the header file api_scilab.h, compile it with ilib_build, write a loader*.sce script and then load it with exec.
P.S.5. supposedly one should be able to install mingw compiler with
atomsInstall('mingw'); atomsLoad('mingw');
However I am not able to get it to work as I have explained here.
This is possible by using, e.g. a C++ Scilab 6 gateway (example needs a compiler on the machine, it should not be a problem for Linux and OSX users):
gw=[
"#include ""double.hxx"""
"#include ""function.hxx"""
"types::Function::ReturnValue sci_incr(types::typed_list &in, int _iRetCount,"
" types::typed_list &out)"
"{"
" if (in.size() != 1 || in[0]->isDouble() == false) {"
" throw ast::InternalError(""Wrong type/number of input argument(s)"");"
" }"
" types::Double *pDbl = in[0]->getAs<types::Double>();"
" double *pdbl = pDbl->get();"
""
" for (int i=0; i < pDbl->getSize(); i++) (*pdbl) += 1.0;"
""
" return types::Function::OK;"
"}"];
cd TMPDIR;
mputl(gw,TMPDIR+"/sci_incr.cpp");
ulink
ilib_build("incr", ["incr" "sci_incr" "cppsci"],"sci_incr.cpp", [])
exec loader.sce
After compilation/link of the interface, you can have the following behavior:
--> x=1
x =
1.
--> incr(x)
--> x
x =
2.
However, don't consider this as a feature, because the Scilab language has not been designed to use it !
For my understanding this is not possible, in scilab input arguments are in the right side of the function and outputs are on the left side. See https://help.scilab.org/docs/6.0.2/en_US/function.html
[output,...] = function(input,...)
So, if you would like an input/output argument you have to assign the input argument to the output one inside your function.
[c] = f1(a, b)
c = a + b
endfunction
And you call it using same variable as input and output argument:
d = 10;
d = f1(d, 1);
I found a solution to extract the contents of a zip file by creating a DLL using Ole. I put my own touch on this function, but for some reason, the compiler complains that the function's result is never used...
library unzipper;
{
title : UnZip for InnoSetup
version : 1.0
author : Daniel P. Stasinski
email : daniel#genericinbox.com
begin : Fri Nov 22 17:31:33 MST 2013
license : None
}
uses
Windows,
SysUtils,
ComObj;
const
SHCONTCH_NOPROGRESSBOX = 4;
SHCONTCH_AUTORENAME = 8;
SHCONTCH_RESPONDYESTOALL = 16;
SHCONTF_INCLUDEHIDDEN = 128;
SHCONTF_FOLDERS = 32;
SHCONTF_NONFOLDERS = 64;
UNZIP_SUCCESS = 0;
UNZIP_FAIL = -1;
function UnzipFile(ZipFile, TargetFolder: WideString): Integer; stdcall;
var
shellobj: variant;
ZipFileV, SrcFile: variant;
TargetFolderV, DestFolder: variant;
shellfldritems: variant;
begin
Result:= UNZIP_FAIL;
try
shellobj := CreateOleObject('Shell.Application');
ZipFileV := string(ZipFile);
TargetFolderV := string(TargetFolder);
SrcFile := shellobj.NameSpace(ZipFileV);
DestFolder := shellobj.NameSpace(TargetFolderV);
shellfldritems := SrcFile.Items;
DestFolder.CopyHere(shellfldritems, SHCONTCH_NOPROGRESSBOX or SHCONTCH_RESPONDYESTOALL);
Result:= UNZIP_SUCCESS;
except
on e: exception do begin
Result:= GetLastError;
end;
end;
end;
exports
UnzipFile;
begin
end.
It gives me the message...
[DCC Hint] Unzipper.dpr(35): H2077 Value assigned to 'UnzipFile' never used
This is coming from the first line of code in the function, which I'm initializing to a constant of -1 - which is my own error code if the entire function fails. I don't believe the compiler should be complaining about this, but I could be wrong. I always exterminate all compiler hints and warnings, but in this case, the compiler is more of a complainer.
Is this a fluke in the compiler, or is something wrong in the code?
The compiler is correct, and there's something wrong in the code. :-)
The function will either return UNZIP_SUCCESS if it works, or the result of GetLastError if an exception is raised. Therefore, the first assignment to Result is unnecessary - there is no path of execution that would cause UNZIP_FAIL to be returned.
If you remove the first line result assignment, there is no execution path that leaves result unassigned. Therefore, UNZIP_FAIL value will never be returned.
The AutoHotkey command Hotkey allows for the creation of dynamic hotkeys at runtime, but its syntax and documentation seems to limit it to built-in or existing labels/subroutines, which makes it much less useful:
Hotkey, KeyName [, Label, Options]
Is there a way to get it to work like regular, hard-coded hotkeys? For example:
#z::MsgBox foobar ; Typical, hard-coded hotkey pops up a message-box
Hotkey, z, MsgBox foobar ; Nope; complains about missing label “MsgBox foobar”
It looks like it might be possible due to the following line from the manual, however it is not clear how it would work:
Label - Both normal labels and hotkey/hotstring labels can be used.
This is a refinement of FakeRainBrigand's answer. It is used exactly the same:
Hotkey("x", "Foo", "Bar") ; this defines: x:: Foo("Bar")
Changes from the original:
Prevent accidental auto-execute of the handler subroutine by tucking it into the function.
Allowing me to reduce namespace pollution by narrowing the scope of the hotkeys variable from global to static.
Optimizations: fun is looked up only once (using Func()) at hotkey definition time; At invocation time, object lookups reduced four to two by splitting hotkeys into two objects funs and args;
This still relies of course on the _L version of AutoHotKey because of Object notation and variadic arg* syntax.
Hotkey(hk, fun, arg*) {
Static funs := {}, args := {}
funs[hk] := Func(fun), args[hk] := arg
Hotkey, %hk%, Hotkey_Handle
Return
Hotkey_Handle:
funs[A_ThisHotkey].(args[A_ThisHotkey]*)
Return
}
Doing exactly what you want isn't possible in AutoHotkey. This is the closest way I can think of.
Call this file Hotkeys.ahk, and put it in My Documents/AutoHotkey/Lib. Alternatively make a folder called Lib, and put it in the same directory as your main script.
Hotkeys := {}
Hotkey(hk, fun, p*) {
global hotkeys
hotkeys[hk] := {}
hotkeys[hk].fun := fun
hotkeys[hk].p := p
Hotkey, %hk%, HandleHotkey
}
HandleHotkey:
hotkeys[A_ThisHotkey].fun(hotkeys[A_ThisHotkey].p*)
return
Here's an example script that you could use it with.
Hotkey("e", "msgbox", "foobar")
MsgBox(msg) {
msgbox % msg
}
#Include <Hotkeys>
The first parameter is the hotkey, the second is the function to call, and everything after that is passed to the function.
Is this what you are looking for?
#Persistent
#SingleInstance Force
#installKeybdHook
Hotkey, #z, MyLabel
MyLabel:
MsgBox,OK
Return
With newer ahk version you can now use functions as label argument. See https://www.autohotkey.com/docs/commands/Hotkey.htm
In our code I have the following, for now please ignore the //* bits;
if (data["someKey"] != null)//*
{
CONSOLE_OUT.info("Print some stuff.");
TARGET::myTarget
{
var someString:String = data["someKey"] as String;//*
someController.setSoemthing(someString.indexOf("soemthing") > -1 ? true : false);//*
}
}
I have set up my FlashCS4 to have the TARGET::myTarget compiler constant set to false, meaning that the code within the compiler constant shouldn't be compiled. At the point of execution data["someKey"] evaluates to null meaning the if statement should NOT execute.
When I debug the following code, the lines with //* on them execute, which is strange behaviour. It skips the initial line after the if statement and goes straight to executing the code that shouldn't have been compiled, bearing in mind that it shouldn't enter the if statement anyway. Its almost as if the presence of the compiler constant is causing the if statement to appear to be a single line, and then still executing the code within the wrong scope.
However, if I add an else statement on the end, the code executes fine;
if (data["someKey"] != null)//*
{
CONSOLE_OUT.info("Print some stuff.");
TARGET::myTarget
{
var someString:String = data["someKey"] as String;
someController.setSoemthing(someString.indexOf("soemthing") > -1 ? true : false);
}
}
else
{
CONSOLE_OUT.info("Print some other stuff.");
}
It should also be noted that in the instance where data["someKey"] evaluates to something other than null, the above version will correctly skip (or not compile) the code within the constant.
I just want to find out if this is a bug, or if I am not using the correct syntax for the compiler constant. If you need any more information then please let me know. I've double check my compiler constants, I am using Flash CS4 to compile and targeting Flash Player 10 if that makes a difference.
Its not bug, compiler will strip any if(false) statement so your conditional constant must be wrapped in condition evaluation.
if (data["someKey"] != null)//*
{
CONSOLE_OUT.info("Print some stuff.");
if(TARGET::myTarget) // it should be conditional statement
{
var someString:String = data["someKey"] as String;//*
someController.setSoemthing(someString.indexOf("soemthing") > -1 ? true : false);//*
}
}
If you look at flex sample, they have applied symbol outside method declaration, so when you write conditional compilation symbol outside member body, member body is included/excluded, but in case of inline statement, flex has no way to determine what to exclude, so it should be used in condition within if.
See answers and links here,
Flash/Flex conditional compilation "else"
I am not sure what you are doing with the TARGET static class.
I have never seen anything like that and without know what TARGET is I wouldn't know how to correct it.
In any case in your if statement you are testing if someKey has a value, however if someKey has not been defined then it wouldn't be null it would be undefined.
With that being said you need to test for it and the proper way to test for it would be like so.
if( data.hasOwnProperty("someKey"){
CONSOLE_OUT.info("Print some stuff.");
TARGET::myTarget <<<<<<< WTH is this????????
{
var someString:String = data["someKey"] as String;
someController.setSoemthing(someString.indexOf("soemthing") > -1 ? true : false);
} }
Also Note that the characters "/*" denote the start of a comment block and all code after that will be commented out.
For example
/* this would be commented
this would be commented
*/
this line would not be commented
[EDIT]
Notice how the first "i.e" is showing the property as undefined.
trace(null == undefined); //Outputs true
trace(null === undefined); //Outputs false
var i:Object;
trace(i); //Outputs null
i = {};
trace(i); //Outputs [object Object]
var i:Object = {a:"b", c:"d"};
trace(i.e); //Outputs undefined
i.e = "f";
trace(i.e); //Outputs f
reference
I need my program to catch TimeOutException every time SerialPort Read Times out, but it fails to do that. In fact, the program breaks when it goes to read and throws this exceptions, "The I/O operation has been aborted because of either a thread exit or an application request."
Here is how SerialPort Instantiated:
dxComm = class(System.Windows.Forms.Form)
private
protected
public
constructor;
serialPort1:System.IO.Ports.SerialPort;
thr:Thread;
method mythread;
end;
constructor DXComm;
begin
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
SerialPort1 := new System.Io.Ports.SerialPort();
thr:=nil;
end;
Here is how thread is created:
thr:= new Thread(#mythread);
thr.Start;
Here is the SerialPort settings:
case TypeDXCard.SelectedIndex of
0:
begin
DXProtocol := TDXProtocol.tDxTwo;
msglen := 6;
rmsglen := 5;
end;
1:
begin
DXProtocol := TDXProtocol.tDxExpress;
msglen:=0;
rmsglen:=0;
end;
else
begin
DXProtocol := TDXProtocol.tDxTwo;
msglen := 6;
rmsglen := 5;
end;
end;
dx := ord(DXProtocol);
if (SerialPort1 <> nil) then
begin
case CommPort.SelectedIndex of
0: SerialPort1.PortName := 'COM1';
1: SerialPort1.PortName := 'COM2';
2: SerialPort1.portName := 'COM3';
3: SerialPort1.PortName := 'COM4';
end;
case BaudRate.SelectedIndex of
0: SerialPort1.BaudRate := 1200;
1: SerialPort1.BaudRate := 2400;
2: SerialPort1.BaudRate := 4800;
3: SerialPort1.BaudRate := 9600;
4: SerialPort1.BaudRate := 19200;
5: SerialPort1.BaudRate := 38400;
6: SerialPort1.BaudRate := 57600;
7: SerialPort1.BaudRate := 115200;
end;
if (EvenParity.Checked) then
SerialPort1.Parity := System.IO.Ports.Parity.Even
else
SerialPort1.Parity := System.IO.Ports.Parity.None;
end;
with SerialPort1 do
begin
SerialPort1.DataBits:=8;
SerialPort1.DtrEnable:=true;
SerialPort1.ReadBufferSize:= 4096;
SerialPort1.ReadTimeout:=TimeOutDelay*2;
SerialPort1.RtsEnable:=true;
SerialPort1.StopBits:=System.IO.Ports.StopBits.One;
SerialPort1.WriteTimeout:=1000;
SerialPort1.Handshake := HandShake.None;
SerialPort1.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(#MySerialData);
end;
Here is my Thread that handles the SerialPort.Write:
method DXcomm.mythread;
var x,y:Integer;
begin
while true do
begin
Thread.Sleep(ScanTime);
SerialPort1.RtsEnable:=true;
SerialPort1.DiscardOutBuffer;
SendMessage; <---------Assembles the bytes and sends it out
while SerialPort1.BytesToWrite>0 do;
thread.Sleep(4);
SerialPort1.DiscardInBuffer;
SerialPort1.RtsEnable:=false;
if (stopthread) then
break;
end;
end;
Here is the event for reading bytes from the serialport:
method DXComm.MySerialData(sender: System.Object; e:SerialDataReceivedEventArgs);
begin
if not SerialPort1.IsOpen then Exit;
try
SerialPort1.Read(RXMsg,0,5); <------Here is Where my program throws that exception when I check on TimeOutException down below.
if changeFlag then
begin
changeList.IncRxCnt;
FixUpChangeList;
end
else
ActiveUnit.Retreive;
except on ex: TimeOutException do <----This line of code fails.
//except on ex: Exception do <----This line of code works fine, but executes all the time instead of just only when there is an exception.
begin
//TimeOut Exception
ActiveUnit.Timeout;
SerialPort1.DiscardInBuffer;
SerialPort1.DiscardOutBuffer;
end;
end;
end;
What am I doing wrong? I need to catch SerialPort.Read TimeOuts and take appropriate action.
It seems you're using the Serial port as a component on a form but doing the reading / writing in a background thread?
Or, as I got it, you write in a background thread and then read on some other, random, thread (the one that is calling the Event you react on).
That is a problem, because the background thread then (internally) want's to update the Serial Port 'Control', which isn't allowed from Background threads. The problem could also be that the thread waiting to read is interrupted by the other thread that is writing in the infinite loop and thus causes the I/O exception. It's a bit of guessing involved here.
First shot:
You have to either create the Serial Port dynamically (i.e. not putting it on your form but instanciating and configuring it by code) to prevent that or (strongly discouraged though), set System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls to false.
Second shot:
On the other hand I would strongly suggest to make definetly sure that only one thread at all is working with the serial port. Not writing in one thread and reading from another. Do everything that is related to this serial I/O in one single thread. Read OR write, but do not try to do both at the same time from different threads.
Instead of:
SerialPort1.Read(RXMsg,0,5);
Does Delphi have a serial function that returns the number of characters received and waiting to be read?
For example(in probably poor pseudo code):
while (Not Timeout)
{
if (serialport1.characterswaiting)
{
SerialPort1.Read(RXMsg,0,5);
}
}
I believe the problem lies in the fact that I am writing to the serialport in my own thread or user-defined thread and reading from the serialport in another. The event datareceived is part of the main thread of the program, I think.
As pointed out by Sebastian, it makes sense that writing and reading from the same thread should solve my serial communication problem. Indeed, it seems have to solved my serial communication, although it is little less than 100%. That's a timing issue, since my program depends on fixed time delays.
The steps: Within my thread, I write to the serial port and wait for sometime to read the response from the serialport. This seems to have greatly improved the communication, but now I don't wait for the datareceived event to fire once it sees something in the input buffer.
Correct me if I am wrong in my thinking or reasoning.