Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 13.04.2017, 05:47   #1
vovakms
Пользователь
 
Регистрация: 13.04.2017
Сообщений: 13
По умолчанию Использование ф-ций DLL написанной на Си

Уважаемые знатоки C# ,
помогите пожалуйста с решением такого вопроса,
имеется DLL-ка ( на Си ) и к ней заголовок .h ,
на С++ написал небольшую программульку ,
теперь делаю на C#WPF проектик,
проблема у меня в том что передаю в DLL-ку массив структур ,
DLL-ка должна заполнить массив структур,
и потом следующая функция должна использовать этот массив структур
это все на словах , теперь код
это сам код
MainWindow.xaml.cs
Код:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Reflection;
using System.Runtime.InteropServices;
using System.IO;

namespace ComHyTech
{
 public partial class MainWindow : Window
 {
 public MainWindow()
 {
 InitializeComponent();
 }

 struct hcSqlParmT
 {
 public ushort size;
 };

 [StructLayout(LayoutKind.Sequential)]
 unsafe struct hcSqlDstInfoT // Структура "Информация о колонках результата"
 {
 public int aliasno;
 public int fieldno;
 public int type;
 public uint len;
 public uint off;
 public fixed char coder[32];
 public fixed char fname[32];
 public int func;
 public fixed char asname[32];
 public int key;
 public int resno;
 };
 
 [DllImport("hscli.dll")]
 static extern int hcSqlInit(IntPtr dummy);

 [DllImport("hscli.dll")]
 static extern int hcSqlCheckInit();
 
 [DllImport("hscli.dll")]
 static unsafe extern int hcSqlAllocConnect(out int pdb);
 //static unsafe extern int hcSqlAllocConnect(int* pdb);

 [DllImport("hscli.dll")]
 static unsafe extern int hcSqlConnect(int pdb, string server, string login , string password);

 [DllImport("hscli.dll")] 
 static unsafe extern int hcSqlAllocStmt(int pdb, int * pOper);// Создать оператор

 [DllImport("hscli.dll")]
 static unsafe extern int hcSqlSetStmtAttr(int pOper, uint option, void* pValue, uint size);

 [DllImport("hscli.dll")]
 static unsafe extern int hcSqlExecDirect(int pOper, string strSQL);// Выполняем SQLзапрос
 
 [DllImport("hscli.dll")]
 static unsafe extern int hcSqlNumResultCols(int pOper, int* pCol);

 [DllImport("hscli.dll")]
 static unsafe extern int hcSqlRowCount(int pOper, long* pStr);

 [DllImport("hscli.dll")]
 static unsafe extern int hcSqlOpenResults(int pOper, uint *pRecSize);
 
 [DllImport("hscli.dll")]
 static unsafe extern int hcSqlGetStmtAttr(int pOper, uint option, int pos, [In,Out]hcSqlDstInfoT[] pValue, uint size, uint* cnt);

 [DllImport("hscli.dll")]
 static unsafe extern int hcSqlReadResults(int pOper, long gStart, byte[] pBuf, uint wBufSize, uint *cnt);
 
 [DllImport("hscli.dll")]
 static unsafe extern int hcSqlCloseResults(int pOper); // Закрытие доступа к результатам
 [DllImport("hscli.dll")]
 static unsafe extern int hcSqlFreeConnect(int pdb); // Освободить соединение
 [DllImport("hscli.dll")]
 static unsafe extern int hcSqlDone();// Завершение работы

 private unsafe void button_Click(object sender, RoutedEventArgs e)
 {
 int err = -300000;// код ошибки заведомо не существующий
 
 int pdb = 0 ;
 int pOper = 0 ; // идетификатор оператора
 int pCol = 0 ; // кол-во колонок
 long pStr = 0 ; // кол-во строк
 uint pRecSize = 0 ; // размер записи
 uint cntOp = 0 ; // сколько байтов записали в буфер
 long gStart = 0 ; // с какой записи начинаем читать 

 if ((err = hcSqlInit(IntPtr.Zero)) != 0) { return; } // Инициализация клиентской части 
 
 textBox_Copy3.AppendText("Инициализация клиентской части err = " + err.ToString() + "\r\n");

 err = hcSqlCheckInit(); // Проверка завершения инициализации
 
 textBox_Copy3.AppendText("Проверка завершения инициализации err = " + err.ToString() + "\r\n") ;

 unsafe
 {
 err = hcSqlAllocConnect (out pdb ) ; // Создать соединение
 textBox_Copy3.AppendText ("Создать соединение err = " + err.ToString() + "\r\n" );
 textBox_Copy3.AppendText ("соединение pdb = " + pdb.ToString() + "\r\n" );
 err = hcSqlConnect (pdb, textBox.Text.ToString() , textBox1.Text.ToString(), textBox2.Text.ToString()); //Установить связь с СУБД
 textBox_Copy3.AppendText ("Установить связь с СУБД err = " + err.ToString() + "\r\n");
 err = hcSqlAllocStmt (pdb, &pOper ); // Создать оператор
 textBox_Copy3.AppendText ("Создать оператор err = " + err.ToString() + "\r\n" );
 textBox_Copy3.AppendText ("оператор pOper = " + pOper.ToString() + "\r\n" );
 err = hcSqlSetStmtAttr (pOper, 1001, (void*)1, 0 ); // ф-ция "Изменение параметров оператора"
 textBox_Copy3.AppendText ("ф-ция Изменение параметров оператора err = " + pOper.ToString() + "\r\n");
 err = hcSqlExecDirect (pOper, textBox3.Text.ToString() ); // Выполняем SQLзапрос
 textBox_Copy3.AppendText ("Выполняем SQLзапрос = " + pOper.ToString() + "\r\n" );

 err = hcSqlNumResultCols (pOper, &pCol); // Получить кол-во колонок результата
 textBox_Copy3.AppendText("кол-во колонок = " + pCol.ToString() + "\r\n");
 err = hcSqlRowCount (pOper, &pStr); // Получить кол-во строк результата
 textBox_Copy3.AppendText("кол-во строк = " + pStr.ToString() + "\r\n");
 err = hcSqlOpenResults (pOper, &pRecSize); // Открытие результатов для чтения
 textBox_Copy3.AppendText("размер записи = " + pRecSize.ToString() + "\r\n");
 
 hcSqlDstInfoT[] infCol = new hcSqlDstInfoT[pCol]; // Структура "Информация о колонках результата" 
 // fixed (hcSqlDstInfoT* pinfCol = &infCol[0])
 err = hcSqlGetStmtAttr(pOper, 107, 0, infCol , (uint)pCol * 128 , &cntOp);// Получить информацию об операторе

 uint cntOut = 0;

 byte[] bufOut = new byte[pRecSize * pStr]; // Адрес буфера для присылаемых записей.
 // fixed (byte* pbufOut = &bufOut[0] )
 // err = hcSqlReadResults(pOper, 0, bufOut, pRecSize * (uint)pStr, &cntOut );// Чтение результатов
 
 // byte p = bufOut; 
  
 for (long i = 0; i < pStr; i++)// идем по строкам
 {
  for (int j = 0; j < pCol; ++j)// идем по колонкам
  {
    switch (infCol[j].type)// в зависимости от типа колонки преобразовываем в соответствующий тип
    {
     case 0: // 0 Массив символов длиной не более заданной 
      //string s(p, infCol[j].len);
       textBox_Copy3.AppendText( infCol[j].type + " "); 
      break;
    }
    // p += infCol[j].len;
   }
   textBox_Copy3.AppendText( "\r\n"); 
 }
 hcSqlCloseResults(pOper); // Закрытие доступа к результатам
 hcSqlFreeConnect(pdb); // Освободить соединение
 hcSqlDone(); // Завершение работы
 }
 }
 }
}
vovakms вне форума Ответить с цитированием
Старый 13.04.2017, 06:51   #2
vovakms
Пользователь
 
Регистрация: 13.04.2017
Сообщений: 13
По умолчанию

если кого заинтересует то
код на С++
сама DLL-ка и зависимые DLL-ки и .h
и непосредственно архив с СУБД HyTech и с тестовой БД (саму HyTech даже устанвливать не надо распаковывается на диск D:\ и запускается все работает)

все это тут https://github.com/vovakms/dbms-HyTech_edition_C
vovakms вне форума Ответить с цитированием
Старый 13.04.2017, 06:56   #3
vovakms
Пользователь
 
Регистрация: 13.04.2017
Сообщений: 13
По умолчанию

несколько материала нашлось
http://www.cyberforum.ru/csharp-net/...2135.html#a_44
но не пойму как применить под себя
vovakms вне форума Ответить с цитированием
Старый 13.04.2017, 07:08   #4
vovakms
Пользователь
 
Регистрация: 13.04.2017
Сообщений: 13
По умолчанию

у меня конкретно не получается вот это место
Цитата:
hcSqlDstInfoT[] infCol = new hcSqlDstInfoT[pCol]; // Структура "Информация о колонках результата"
err = hcSqlGetStmtAttr(pOper, 107, 0, infCol , (uint)pCol * 128 , &cntOp);// Получить информацию об операторе
ошибку не выдает но и структура не заполняется, получается я не правельно передаю структуру

проект в MSVS2015C#WPF в настройках выставил "Разрешить небезопасный код"

Последний раз редактировалось Alex11223; 19.04.2017 в 07:57.
vovakms вне форума Ответить с цитированием
Старый 14.04.2017, 07:13   #5
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,709
По умолчанию

[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] указатель маршалить надо, как и некоторые другие параметры
p51x вне форума Ответить с цитированием
Старый 14.04.2017, 12:05   #6
Вовантус
Пользователь
 
Регистрация: 24.05.2012
Сообщений: 16
По умолчанию

Цитата:
Сообщение от p51x Посмотреть сообщение
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] указатель маршалить надо, как и некоторые другие параметры
спасибо , подскажите куда мне это вписать
Вовантус вне форума Ответить с цитированием
Старый 14.04.2017, 12:14   #7
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,709
По умолчанию

В объвление нативной функции, где указатель нужен.
p51x вне форума Ответить с цитированием
Старый 19.04.2017, 07:28   #8
vovakms
Пользователь
 
Регистрация: 13.04.2017
Сообщений: 13
По умолчанию

ОК большое спасибо , вопрос решен

если кому будет интересно , вот все исходники https://github.com/vovakms

Последний раз редактировалось Alex11223; 19.04.2017 в 07:59.
vovakms вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Работа с dll написанной на Delphi mihalech19 C++ Builder 12 11.08.2014 14:02
Импорт *.dll, написанной на c++ в WinForms c# ImmortalAlexSan C# (си шарп) 5 02.07.2014 17:51
C# импорт метода из Dll написанной на C++ head-dron Общие вопросы .NET 1 27.09.2010 20:57
Использование длл, написанной на С++, в программе на ВБ 6 Гончий Общие вопросы C/C++ 18 01.06.2010 19:12
Объясните использование ф-ций Molotok Microsoft Office Excel 5 21.09.2008 18:32