从 vb.net 调用 dll 函数

如何解决从 vb.net 调用 dll 函数

我有一个名为 plclient_kompas.dll 的 CAD dll。这是一个标准机械制造零件库。

plclient_kompas.dll中包含函数PLInsert3D,将标准零件从库中放入3D装配。

在这个库的手册中说:

HRESULT **PLInsert3D**(
[in] IPARTLibProvider* aPLClient;
[in] IBOResponseDisp* aMethodResponse;
[in] ksPlacement* aPlacement;
[out,retval] IDispatch** result);

所以我想从 vs2017 vb.net 代码中调用这个函数,如下所示:

<DllImport("C:\Program Files\ASCON\KOMPAS-3D v17\Libs\PARTLib\Clients\plclient_kompas.dll",CallingConvention:=CallingConvention.StdCall)>

Public Shared Function **PLInsert3D**(aPLClient As IPARTLibProvider,aMethodResponse As BOResponse,aPlacement As ksPlacement) As ksPart

End Function 


Private Sub Button1_Click(sender As Object,e As EventArgs) Handles Button1.Click

iMainPart = **PLInsert3D**(aPLClient,aMethodResponse,aPlacement)

End Sub

但在这一行:

iMainPart = **PLInsert3D**(aPLClient,aPlacement) 

我有错误访问冲突异常。

我做错了什么?任何帮助将不胜感激。谢谢!

补充一下我写的。 这是我在 vb.net 中的代码:

Imports Kompas6API5
Imports KompasAPI7
Imports PARTLibClient
Imports BOSimple
Imports Kompas6Constants3D
Imports System.Runtime.InteropServices
Imports stdole

Public Class Form1
    
    <DllImport("C:\Program Files\ASCON\KOMPAS-3D v17\Libs\PARTLib\Clients\plclient_kompas.dll",CallingConvention:=CallingConvention.StdCall)>
    Public Shared Function PLInsert3D(ByRef aPLClient As IPARTLibProvider,ByRef aMethodResponse As BOResponse,ByRef aPlacement As ksPlacement) As <MarshalAs(UnmanagedType.Interface)> ksPart
    End Function

    Private Sub Button1_Click(sender As Object,e As EventArgs) Handles Button1.Click

        Dim kompas As Object
        Dim ksdoc As Object

        kompas = New Kompas6API5.Application

        kompas.Visible = True

        ksdoc = kompas.Document3D
        ksdoc.Create(False,False)

        ksdoc.Filename = "C:\Users\Baha1990\Documents\Visual Studio 2017\Projects\Kompas3D\3d files\1.a3d"
        ksdoc.UpdateDocumentParam
        ksdoc.Save

        Dim aPLClient As BOSimpleProvider
        aPLClient = New PARTLibClient.BOSimpleProvider

        Dim Location As String
        Dim Response As Object
        Location = ""
        Response = aPLClient.SelectEx(0,Location,0)

        Dim aMethodResponse As BOResponse
        aMethodResponse = aPLClient.GetMethod(Location,"КОМПАС 3D")

        Dim iDoc3D As ksDocument3D
        Dim iMainPart As ksPart
        Dim aPlacement As ksPlacement
        
        iDoc3D = kompas.ActiveDocument3D

        iMainPart = iDoc3D.GetPart(-1)
              
        aPlacement = iMainPart.GetPlacement
        aPlacement.SetOrigin(0,0)

        iMainPart = PLInsert3D(aPLClient,aPlacement)

    End Sub

这是来自 C# API 手册的示例:

// Тестовая библиотека вставки объекта в КОМПАС из СИ
/*
 * Необходимо у подключаемых библиотек BOSimple и PARTLibClient выставить значение параметра
 * Embed Interop Types = False
 *
 * */
using System;
using Microsoft.Win32;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using KAPITypes;
using Kompas6Constants;
using Kompas6API5;
using Kompas6API7;
using PARTLibClient;
using BOSimple;
using Kompas6Constants3D;
using stdole;

using System.Runtime.Versioning;

namespace PartLibAPI

{
    [ClassInterface(ClassInterfaceType.AutoDual)]
    public class InsertKompas
    {
        const string _LIBRARYNAME = "Вставка изделия в Компас из СИ";
        const string _KEYNAME = @"SOFTWARE\Classes\CLSID\{";
        const string _KOMPASLIBRARY = "Kompas_Library";
        const string _DLLPATH = "plclient_kompas.dll";
        const string _KERNEL32 = "kernel32.dll";

        #region Методы для работы библиотеки в Компас

        private KompasObject _kompas;
        // Название библиотеки
        [return: MarshalAs(UnmanagedType.BStr)]
        public string GetLibraryName()
        {
            return _LIBRARYNAME;
        }

        // Головная функция библиотеки

        public void ExternalRunCommand([In] short command,[In] short mode,[In,MarshalAs(UnmanagedType.IDispatch)] object kompas_)
        {
            _kompas = (KompasObject)kompas_;
            switch (command)
            {
                case 1:
                    InsertInKompas(_kompas);
                    break;
            }
        }

        // Функция получения меню
        // Описание функции можно найти в SDK API Компас
        [return: MarshalAs(UnmanagedType.BStr)]
        public string ExternalMenuItem(short number,ref short itemType,ref short command)
        {
            var result = string.Empty;
            itemType = 1; // "MENUITEM"
            switch (number)
            {
                case 1:
                    result = "Вставить";
                    command = 1;
                    break;
                //
                // Для корректной работы библиотеки необходимо добавить конец меню (или подменю)
                //
                case 2:
                    command = -1;
                    itemType = 3; // "ENDMENU"
                    break;
            }
            return result;
        }
        #endregion

        // Делегаты для работы с методами из plclient_kompas.dll
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        private delegate int _PLInsert2D(IPARTLibProvider aPLClient,IBOResponse aMethodResponse,double aX,double aY,double aAngle);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        private delegate void _PLInsert3D([Out] out IDispatch retVal,IPARTLibProvider aPLClient,ksPlacement aPlacement);
        private void InsertInKompas(KompasObject kompas)
        {
            // Подключаемся к plclient_kompas.dll (получаем ссылку на запущенный экземпляр в процессе Компаса)
            IntPtr pDll = IntPtr.Zero;
            try
            {
                pDll = LoadLibrary(_DLLPATH);
                if (pDll == IntPtr.Zero)
                    throw new Exception("Не могу найти plclient_kompas.dll");
                // Получаем адреса экспортируемых функций из ранее загруженной plclient_kompas.dll
                var pProc2D = GetProcAddress(pDll,"PLInsert2D");
                var pProc3D = GetProcAddress(pDll,"PLInsert3D");

                // Получаем экземпляры делегатов,приведенных к соответствующему типу
                var PLInsert2D = (_PLInsert2D)Marshal.GetDelegateForFunctionPointer(pProc2D,typeof(_PLInsert2D));
                var PLInsert3D = (_PLInsert3D)Marshal.GetDelegateForFunctionPointer(pProc3D,typeof(_PLInsert3D));

                IApplication kompasApp = kompas.ksGetApplication7();
                if (kompasApp == null)
                    throw new Exception("Не удалось получить указатель на интерфейс приложения!");
                var doc2D = (Document2D)kompas.ActiveDocument2D();
                var doc3D = (Document3D)kompas.ActiveDocument3D();
                if ((doc2D == null) && (doc3D == null))
                    throw new Exception("Откройте документ или создайте новый!");
                // Подключаемся к API справочника
                IPARTLibProvider PLClient = null;
                try
                {
                    PLClient = new BOSimpleProvider();
                    var errorMsg = String.Empty; 
                    // Подключаемся к серверу приложений
                    if (PLClient.Connect(ref errorMsg) == 0)
                    {
                        try
                        {
                            // Получаем доступ к изделиям и папкам в справочнике
                            var commonData = PLClient.CreateCommonDataObj();
                            commonData.InitUserData();
                            string plm2D = "2D"; // Документ 2D
                            string plm3D = "Solid3D"; // Документ 3D

                            // Типы документов Компаса

                            string[] methodNames = { "","КОМПАС 2D","КОМПАС 3D","" };
                            string[] docName = { "?",plm2D,plm3D,"?" };

                            // Получаем тип документа

                            var docType = GetDocType(kompasApp);

                            ksPart mainPart = null;

                            ksPart pPart = null;

                            ksPlacement partPlace = null;

                            if (docType == DocumentTypeEnum.ksDocumentAssembly)

                            {

                                if (doc3D != null)

                                {

                                    mainPart = doc3D.GetPart((short)Part_Type.pTop_Part);

                                    if (mainPart != null)

                                    {

                                        pPart = doc3D.GetPart(0);

                                        partPlace = pPart != null ? pPart.GetPlacement() : mainPart.GetPlacement();

                                 }

                               }

                           }

                            // Задаем режим работы справочника в зависимости от типа активного документа в КОМПАС

                            commonData.SetFindOptions(docName[(int)docType]);

                            // Путь до корневого каталога с ISO стандартами по уникальному ID

                            var ISOFolder = commonData.FolderByID("A259_151417DFF6474BF6");

                            // Просматриваем каталог в глубину

                            while (ISOFolder.FolderCollection().Count() > 0)

                            {

                                ISOFolder = ISOFolder.FolderCollection().Folder(0);

                                // В случае если в каталоге есть хотя бы один класс

                                if (ISOFolder.ClassCollection().Count() > 0)

                                {

                                    // Получаем указатель на интерфейс первой типоразмерной таблицы его изделий

                                    var ISOClass = ISOFolder.ClassCollection().plClass(0);

                                    var instance = ISOClass.Instances("",docName[(int)docType]);

                                    var paramGrid = instance.ParamGrid(0);                                  

                                    // Просматриваем типоразмерную таблицу сверху-вниз

                                    for (int i = 0; i < paramGrid.PGRowCount(); i++)

                                    {

                                        // Выбираем строку

                                        paramGrid.SelectRow(i);

                                        // Получаем полный location получившегося изделия

                                        var location = instance.plPart().GetLocation(0);

                                        // Получаем метод для вставки изделия в зависимости от типа активного документа

                                        var methodResponce = PLClient.GetMethod(location,methodNames[(int)docType]);


                                        // Вставляем изделие в КОМПАС

                                        var X = 5 * i * Math.Sin(15 * Math.PI * i / 180);

                                        var Y = 5 * i * Math.Cos(15 * Math.PI * i / 180);

                                        var Angle = 180 - i * 15;

                                        IDispatch kPart;

                                        switch (docType)

                                        {

                                            case DocumentTypeEnum.ksDocumentAssembly:

                                                // Задаем место в сборке

                                                partPlace.SetOrigin(X,Y,0);

                                                PLInsert3D(out kPart,PLClient,methodResponce,partPlace);

                                                break;

                                            case DocumentTypeEnum.ksDocumentDrawing:

                                                PLInsert2D(PLClient,X,Angle);

                                                break;

                                            case DocumentTypeEnum.ksDocumentFragment:

                                                PLInsert2D(PLClient,Angle);

                                                break;

                                            case DocumentTypeEnum.ksDocumentSpecification:

                                                PLInsert3D(out kPart,null);

                                                break;

                                        }

                                    }

                                }

                            }

                        }

                        catch (Exception ex)

                        {

                            kompas.ksMessage(ex.Message);

                        }

                        finally

                        {

                            // Отключаемся от сервера приложений

                            PLClient.Disconnect();

                        }

                    }

                    else

                        kompas.ksMessage("Ошибка подключения к серверу приложений: " + errorMsg);

                }

                catch (Exception ex)

                {

                    kompas.ksMessage("Ошибка! Не удалось создать COM-объект." + ex.Message);

                }

            }

            catch (Exception ex)

            {

                kompas.ksMessage(ex.Message);

            }

            finally

            {

                // Освобождаем загруженную plclient_kompas.dll

                FreeLibrary(pDll);

            }

        }

 
        /// <summary>

        /// Метод определения типа документа

        /// </summary>

        /// <param name="kompasApp"></param>

        /// <returns></returns>

        private DocumentTypeEnum GetDocType(IApplication kompasApp)

        {

            return kompasApp.ActiveDocument == null ? DocumentTypeEnum.ksDocumentUnknown : kompasApp.ActiveDocument.DocumentType;

        }

        // Импортируем в проект методы из kernel32.dll для подключения к plclient_kompas.dll

        [DllImport(_KERNEL32,CharSet = CharSet.Unicode,SetLastError = true)]

        [ResourceExposure(ResourceScope.Process)]

        public static extern IntPtr LoadLibrary(string libFilename);

        [DllImport(_KERNEL32,CharSet = CharSet.Ansi,BestFitMapping = false,ThrowOnUnmappableChar = true)]

        static internal extern IntPtr GetProcAddress(IntPtr HModule,[MarshalAs(UnmanagedType.LPStr),In] string funcName/*lpcstr*/);

        [DllImport(_KERNEL32,SetLastError = true)]

        [ResourceExposure(ResourceScope.Process)]

        public static extern bool FreeLibrary(IntPtr hModule);

        #region COM Registration

        // Эта функция выполняется при регистрации класса для COM

        // Она добавляет в ветку реестра компонента раздел Kompas_Library,// который сигнализирует о том,что класс является приложением Компас,// а также заменяет имя InprocServer32 на полное,с указанием пути.

        // Все это делается для того,чтобы иметь возможность подключить

        // библиотеку на вкладке ActiveX.

        [ComRegisterFunction]

        public static void RegisterKompasLib(Type t)

        {

            RegistryKey regKey = Registry.LocalMachine;

            try

            {

                var keyName = string.Format("{0}{1}{2}",_KEYNAME,t.GUID.ToString(),"}");

                regKey = regKey.OpenSubKey(keyName,true);

                regKey.CreateSubKey(_KOMPASLIBRARY);

                regKey = regKey.OpenSubKey("InprocServer32",true);

                regKey.SetValue(null,System.Environment.GetFolderPath(Environment.SpecialFolder.System) + @"\mscoree.dll");

            }

            catch (Exception ex)

            {

                MessageBox.Show(string.Format("При регистрации класса для COM-Interop произошла ошибка:\n{0}",ex));

            }

            finally

            {

                regKey.Close();

            }

        }

        // Эта функция удаляет раздел Kompas_Library из реестра

        [ComUnregisterFunction]

        public static void UnregisterKompasLib(Type t)

        {

            RegistryKey regKey = Registry.LocalMachine;

            var keyName = string.Format("{0}{1}{2}","}");

            RegistryKey subKey = regKey.OpenSubKey(keyName,true);

            try

            {

                subKey.DeleteSubKey(_KOMPASLIBRARY);

            }

            finally { subKey.Close(); }

        }

        #endregion

    }

}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-