[DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl,
EntryPoint = "?acedSetCurrentView@@YA?AW4ErrorStatus@Acad@@PAVAcDbViewTableRecord@@PAVAcDbViewport@@@Z")]
private static extern int acedSetCurrentView(IntPtr pVtr, /*IntPtr.Zero*/IntPtr pVP);
[DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl, EntryPoint = "acedTrans")]
static extern int acedTrans(double[] point, IntPtr fromRb, IntPtr toRb, int disp, double[] result);
[DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl,
EntryPoint = "?acedVports2VportTableRecords@@YA?AW4ErrorStatus@Acad@@XZ")]
private static extern bool acedVports2VportTableRecords();
[DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl,
EntryPoint = "?acedVportTableRecords2Vports@@YA?AW4ErrorStatus@Acad@@XZ")]
private static extern bool acedVportTableRecords2Vports();
Since p/invoke methods sometimes have different entry points due to name mangling, maybe it would be a good idea to specify the Acad version.Would be interesting to see the example of usage as well...:)
extern "C" __declspec(dllexport)
void steelMEPcollisions (map<AcDbObjectId, double> pipeDiamMap) { ... }
[DllImport(STEEL_ARX, CallingConvention = CallingConvention.Cdecl, EntryPoint = "steelMEPcollisions ")]
public static extern void CollisionsSteelMEP ( Dictionary<ObjectId, Double> pipeDiamMap );
Like from unmanaged:Code: [Select]extern "C" __declspec(dllexport)
void steelMEPcollisions (map<AcDbObjectId, double> pipeDiamMap) { ... }
I which the above could be to easy like to managed:Code: [Select][DllImport(STEEL_ARX, CallingConvention = CallingConvention.Cdecl, EntryPoint = "steelMEPcollisions ")]
public static extern void CollisionsSteelMEP ( Dictionary<ObjectId, Double> pipeDiamMap );
// C++ - unmanaged
extern "C" __declspec(dllexport)
void steelMEPcollisions ( resbuf *pArgs ) { ... }
// C# - managed
public static class SteelFunctions
{
[DllImport(STEEL_ARX, CallingConvention = CallingConvention.Cdecl, EntryPoint = "steelMEPcollisions ")]
public static extern void CollisionsSteelMEP ( IntPtr pArgs );
}
public static void CollisionsMEPSteel ( ResultBuffer args )
{
SteelFunction.CollisionsSteelMEP( args.UnmanagedObject );
}
ResultBuffer args = new ResultBuffer();
args.Add(new TypedValue((int)LispDataType.ListBegin, -1));
args.Add(new TypedValue((int)LispDataType.ListBegin, -1));
args.Add(new TypedValue((int)LispDataType.Int32, oldIdPtr.ToInt32()));
args.Add(new TypedValue((int)LispDataType.Double, diam));
args.Add(new TypedValue((int)LispDataType.ListEnd, -1));
args.Add(new TypedValue((int)LispDataType.ListEnd, -1));
PInvoke.CollisionsMEPSteel(args);
'#define AC_SRCH_BLOCK 0x01
'#define AC_SRCH_DIM_TEXT 0x02
'#define AC_SRCH_TEXT 0x04
'#define AC_SRCH_LINK_DESC 0x08
'#define AC_SRCH_LINK_URL 0x10
'#define AC_SRCH_MATCH_CASE 0x20
'#define AC_SRCH_WHOLE_WORD 0x40
'#define AC_SRCH_DEFAULT 0x1F
'bool acdbTextFind(AcDbDatabase* pDatabase,
' AcDbObjectIdArray& resultSet,
' const ACHAR* findString,
' const ACHAR* replaceString = NULL,
' Adesk::UInt8 searchOptions = AC_SRCH_DEFAULT,
' const AcDbObjectIdArray& selSet = 0);
Public Const AC_SRCH_BLOCK As Integer = 1
Public Const AC_SRCH_DIM_TEXT As Integer = 2
Public Const AC_SRCH_TEXT As Integer = 4
Public Const AC_SRCH_LINK_DESC As Integer = 8
Public Const AC_SRCH_LINK_URL As Integer = 16
Public Const AC_SRCH_MATCH_CASE As Integer = 32
Public Const AC_SRCH_WHOLE_WORD As Integer = 64
Public Const AC_SRCH_DEFAULT As Integer = 31
<DllImport("acdb17.dll", CallingConvention:=CallingConvention.Cdecl, CharSet:=CharSet.Unicode, EntryPoint:="?acdbTextFind@@YA_NPAVAcDbDatabase@@AAV?$AcArray@VAcDbObjectId@@V?$AcArrayMemCopyReallocator@VAcDbObjectId@@@@@@PB_W2EABV2@@Z")> _
Private Shared Function acdbTextFind(ByVal pDb As System.IntPtr, _
ByVal resultSet As System.IntPtr, _
<System.Runtime.InteropServices.InAttribute(), System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)> ByVal findString As String, _
<System.Runtime.InteropServices.InAttribute(), System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)> ByVal replaceString As String, _
ByVal searchOptions As Integer, _
ByVal selSet As System.IntPtr) As <System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.I1)> Boolean
End Function
Public Shared Sub ZZ()
Dim oidIn As New ObjectIdCollection
Dim oidOut As New ObjectIdCollection
Dim ret As Boolean
Dim db As Database = Application.DocumentManager.MdiActiveDocument.Database
ret = acdbTextFind(db.UnmanagedObject, oidOut.UnmanagedObject, "hello", Nothing, AC_SRCH_DEFAULT, oidIn.UnmanagedObject)
If ret Then
For Each id As ObjectId In oidOut
'
Next
End If
oidIn.Dispose()
oidOut.Dispose()
End Sub
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.ApplicationServices
Imports System.Runtime.InteropServices 'for DllImport()
Imports System.Security
<System.Security.SuppressUnmanagedCodeSecurity(), DllImport("acad.exe", CallingConvention:=CallingConvention.Cdecl)> _
Private Shared Function acedInvoke(ByVal rbIn As IntPtr, <Out()> ByRef rbOut As IntPtr) As Integer
End Function
Public Shared Function InvokeLisp(ByVal resbuf As ResultBuffer) As ResultBuffer
Dim rb As IntPtr = IntPtr.Zero
Class1.acedInvoke(resbuf.UnmanagedObject, rb)
Return DirectCast(DisposableWrapper.Create(GetType(ResultBuffer), rb, True), ResultBuffer)
End Function
Peter,
Isn't that the code gile posted for you elsewhere ??
Regards,
Peter,
Isn't that the code gile posted for you elsewhere ??
Regards,
[DllImport("acad.exe")]
public static extern void acedPostCommandPrompt ( );
Imports System.Drawing
Imports System.Runtime.InteropServices
#If ACAD_17 Then
Const ACDBDLL_NAME = "acdb17.dll"
#Else
Const ACDBDLL_NAME = "acdb18.dll"
#End If
<System.Runtime.InteropServices.DllImportAttribute(ACDBDLL_NAME, CallingConvention:=CallingConvention.Cdecl, CharSet:=CharSet.Unicode, EntryPoint:="?acdbGetPreviewBitmapFromDwg@@YA_NPB_WPAPAUHBITMAP__@@PAPAUHPALETTE__@@@Z")> _
Private Shared Function acdbGetPreviewBitmapFromDwg32(<System.Runtime.InteropServices.InAttribute(), System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)> ByVal pszDwgfilename As String, ByRef pPreviewBmp As System.IntPtr, ByRef pRetPal As System.IntPtr) As <System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.I1)> Boolean
End Function
<System.Runtime.InteropServices.DllImportAttribute(ACDBDLL_NAME, CallingConvention:=CallingConvention.Cdecl, CharSet:=CharSet.Unicode, EntryPoint:="?acdbGetPreviewBitmapFromDwg@@YA_NPEB_WPEAPEAUHBITMAP__@@PEAPEAUHPALETTE__@@@Z")> _
Private Shared Function acdbGetPreviewBitmapFromDwg64(<System.Runtime.InteropServices.InAttribute(), System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)> ByVal pszDwgfilename As String, ByRef pPreviewBmp As System.IntPtr, ByRef pRetPal As System.IntPtr) As <System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.I1)> Boolean
End Function
Private Function GetPreviewBitmapFromDwg(ByVal fileName As String) As Bitmap
Dim hBmp As System.IntPtr
Dim hPal As System.IntPtr
If IntPtr.Size > 4 Then ' 64-bit
acdbGetPreviewBitmapFromDwg64(fileName, hBmp, hPal)
Else ' 32-bit
acdbGetPreviewBitmapFromDwg32(fileName, hBmp, hPal)
End If
If hBmp.Equals(IntPtr.Zero) Then
Return Nothing
Else
Return Bitmap.FromHbitmap(hBmp)
End If
End Function
#if ACAD_17
private const string ACDBDLL_NAME = "acdb17.dll";
#else
private const string ACDBDLL_NAME = "acdb18.dll";
#endif
[return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.I1)]
[System.Runtime.InteropServices.DllImportAttribute(ACDBDLL_NAME, CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Unicode, EntryPoint="?acdbGetPreviewBitmapFromDwg@@YA_NPB_WPAPAUHBITMAP__@@PAPAUHPALETTE__@@@Z")]
private extern static bool acdbGetPreviewBitmapFromDwg32([System.Runtime.InteropServices.InAttribute(), System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)] string pszDwgfilename, ref System.IntPtr pPreviewBmp, ref System.IntPtr pRetPal);
[return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.I1)]
[System.Runtime.InteropServices.DllImportAttribute(ACDBDLL_NAME, CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Unicode, EntryPoint="?acdbGetPreviewBitmapFromDwg@@YA_NPEB_WPEAPEAUHBITMAP__@@PEAPEAUHPALETTE__@@@Z")]
private extern static bool acdbGetPreviewBitmapFromDwg64([System.Runtime.InteropServices.InAttribute(), System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)] string pszDwgfilename, ref System.IntPtr pPreviewBmp, ref System.IntPtr pRetPal);
private Bitmap GetPreviewBitmapFromDwg(string fileName)
{
System.IntPtr hBmp = default(System.IntPtr);
System.IntPtr hPal = default(System.IntPtr);
if (IntPtr.Size > 4) // 64-bit
{
acdbGetPreviewBitmapFromDwg64(fileName, ref hBmp, ref hPal);
}
else // 32-bit
{
acdbGetPreviewBitmapFromDwg32(fileName, ref hBmp, ref hPal);
}
if (hBmp.Equals(IntPtr.Zero))
{
return null;
}
else
{
return Bitmap.FromHbitmap(hBmp);
}
}
private void AddToImageList(string filename)
{
Database db = new Database(false, false);
db.ReadDwgFile(filename, FileOpenMode.OpenForReadAndAllShare, false, null);
Bitmap bitmap = db.ThumbnailBitmap;
if (!(DetailsLargeImage.Images.ContainsKey(filename)))
{
DetailsLargeImage.Images.Add(filename, bitmap);
DetailsSmallImage.Images.Add(filename, bitmap);
}
}
I have been playing with this for using lisp.Code: [Select]
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.ApplicationServices
Imports System.Runtime.InteropServices 'for DllImport()
Imports System.Security
<System.Security.SuppressUnmanagedCodeSecurity(), DllImport("acad.exe", CallingConvention:=CallingConvention.Cdecl)> _
Private Shared Function acedInvoke(ByVal rbIn As IntPtr, <Out()> ByRef rbOut As IntPtr) As Integer
End Function
Public Shared Function InvokeLisp(ByVal resbuf As ResultBuffer) As ResultBuffer
Dim rb As IntPtr = IntPtr.Zero
Class1.acedInvoke(resbuf.UnmanagedObject, rb)
Return DirectCast(DisposableWrapper.Create(GetType(ResultBuffer), rb, True), ResultBuffer)
End Function
(defun c:foo ...)
or(defun foo ...) (vl-acad-defun 'foo)
Hi,
I don't think the error is in the code you posted.
/* The following RT codes are for the ADS program interface.
They are used to signal success or failure (error) of the
ADS library functions. RTFAIL in particular means that
the link has failed (most likely because AutoLISP has
died or exited), and the application should cleanup and exit.
*/
#define RTNORM 5100 /* Request succeeded */
/* Various error codes returned to ADS application by library
*/
#define RTERROR (-5001) // Some other error
#define RTCAN (-5002) // User cancelled request -- Ctl-C
#define RTREJ (-5003) // AutoCAD rejected request -- invalid
#define RTFAIL (-5004) // Link failure -- Lisp probably died
#define RTKWORD (-5005) // Keyword returned from getxxx() routine
#define RTINPUTTRUNCATED (-5008) // Input didn't all fit in the buffer
Is it an error not to check for an error?
QuoteIs it an error not to check for an error?
In the sample TonyT gave here (http://forums.autodesk.com/t5/NET/How-to-call-Lisp-functions-from-Net/m-p/1564636), he shows how to use the int returned by acedInvoke as error checking.
Remind that since A2011 .NET SDK there's an Application.Invoke() method which wraps the ObjectARX function acedInvoke().
args.Add(New TypedValue((int)LispDataType.Text, "c:ace_update_WFRM2ALL"))
args.Add(New TypedValue((int)LispDataType.Int16, 1))
Dim rbRes As ResultBuffer = Autodesk.AutoCAD.ApplicationServices.Application.Invoke(args)
Code: [Select]args.Add(New TypedValue((int)LispDataType.Text, "c:ace_update_WFRM2ALL"))
args.Add(New TypedValue((int)LispDataType.Int16, 1))
Dim rbRes As ResultBuffer = Autodesk.AutoCAD.ApplicationServices.Application.Invoke(args)
Relative PathCode - C#: [Select]
[DllImport("shlwapi.dll", CharSet = CharSet.Auto)] static extern bool PathRelativePathTo( StringBuilder path, string fromPath, FileAttributes fromAttr, string toPath, FileAttributes toAttr); static string MakeRelativePathTo(string fromPath, string toPath) { bool done = PathRelativePathTo( builder, fromPath, FileAttributes.Directory, toPath, FileAttributes.Normal); return done ? builder.ToString() : toPath; }
MakeRelativePathTo(@"Z:\Drawings\Blocks", @"Z:\Drawings\Blocks\Arch\Door.dwg"); -> ".\Arch\Door.dwg"
MakeRelativePathTo(@"Z:\Drawings\Blocks", @"Z:\Docs\Help.html"); -> ..\..\Docs\Help.html"